Lambda Proxy Integration

Understand the concept of proxy integration.

Proxy integration

So far, we’ve seen request integration where API Gateway directly passes the input payload into the integration, but API Gateway has more information than that. This information can provide great value.

Echo API

To understand the proxy integration, let’s start by building the Echo API that echoes back our request. Check out the code below.

/**
 * This code is deployed as the Lambda function in AWS. 
 * It just returns the input event as is
 */

exports.handler = async(event, context) => {
  return event;
};

Echo API

Click "Run" to deploy and test the API. The script above invokes the API and displays the result if the deployment is complete. It runs the Echo API that echoes any request payload.

  • Line 7 in index.js returns the event input as-is.

  • Line 32 in template.yml specifies the API name EducativeRestAPI.

  • Line 79 in run.sh invokes the API by posting a sample { "message": "Hello World" } in JSON.

  • Line 53 in template.yml uses type: "aws". It defines the type of integration with the Lambda function.

When this code executes, it echoes this input, and we get the response { "message": "Hello World" }. It works because the event in this code contains the payload passed into the POST method.

Lambda proxy

The API Gateway has a lot of information about the input request apart from the payload itself. It has access to the HTTP headers and a lot of contextual information about the request. However, in the example above, we saw that the Lambda function didn’t get that information.

API Gateway provides another way to integrate a Lambda function which passes all the available information into the event object (not just the payload in the request body). That means that the entire input data (including headers) flows into the Lambda function. Similarly, the lambda response flows back as is to the API response without parsing the headers.

That’s called Lambda proxy integration.

/**
 * This code is deployed as the Lambda function in AWS.
 */

exports.handler = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify(event),
  };
};
Echo API with Proxy Integration

Click "Run" to deploy and test the API. Before that, check the CloudFormation console to ensure that there’s no stale stack from a previous exercise. If there is one, delete it and wait a few minutes until it’s clear.

The script above invokes the API and displays the result if the deployment is complete. This time, the output is much larger than the first run.

This code is almost the same as the Echo API above, except for two differences.

  • Lines 7-8 in index.js return the stringified event object, along with the status code. We have to do this because the proxy integration passes the Lambda response as is to the client. The Lambda function has to manage the success code and any HTTP headers.

  • Line 53 in template.yml specifies the type of Lambda function integration as the proxy integration. The type: "aws_proxy" sets up the Lambda proxy integration.

The proxy integration makes the difference. Now the Lambda function gets all that was available at the API Gateway, not just the input payload. The output looks like this:

Press + to interact
{
"resource": "/hello",
"path": "/hello",
"httpMethod": "POST",
"headers": {
"accept": "*/*",
"content-type": "application/json",
"Host": "1hhhx1jx7f.execute-api.us-east-1.amazonaws.com",
"User-Agent": "curl/7.81.0",
"X-Amzn-Trace-Id": "Root=1-62cb8615-50eb677013e69e210681abe4",
"X-Forwarded-For": "9.3.109.210",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"accept": [
"*/*"
],
"content-type": [
"application/json"
],
"Host": [
"1hhhx1jx7f.execute-api.us-east-1.amazonaws.com"
],
"User-Agent": [
"curl/7.81.0"
],
"X-Amzn-Trace-Id": [
"Root=1-62cb8615-50eb677013e69e210681abe4"
],
"X-Forwarded-For": [
"9.3.109.210"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"resourceId": "z3hy49",
"resourcePath": "/hello",
"httpMethod": "POST",
"extendedRequestId": "VFHjcF1hIAMFpBw=",
"requestTime": "11/Jul/2022:02:08:21 +0000",
"path": "/v1/hello",
"accountId": "1234567890123",
"protocol": "HTTP/1.1",
"stage": "v1",
"domainPrefix": "1hhhx1jx7f",
"requestTimeEpoch": 1657505301833,
"requestId": "1e8d455e-e7b2-415a-9745-b044d8ef4d7d",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "9.3.109.210",
"principalOrgId": null,
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "curl/7.81.0",
"user": null
},
"domainName": "1hhhx1jx7f.execute-api.us-east-1.amazonaws.com",
"apiId": "1hhhx1jx7f"
},
"body": "{ \"message\": \"Hello World\" }",
"isBase64Encoded": false
}

That’s a lot of information. The Lambda proxy integration provides access to a lot of information about the invocation. The response is a massive JSON that includes the source IP address, the source agent, all the headers in the input request, and much more. Look at the JSON response above and imagine different use cases where we can use this information. That’s handy information!

Web console

Let's peek at the API Gateway web console to see what has changed there. Then, open the API, resource, method, and finally, click on the “Integration Request” link.

Press + to interact
Lambda proxy integration
Lambda proxy integration

Note that it has checked the tiny checkbox highlighted in the image. That’s what made the difference.