Lambda Proxy Integration
Understand the concept of proxy integration.
We'll cover the following
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; };
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 theevent
input as-is.Line 32 in
template.yml
specifies the API nameEducativeRestAPI
.Line 79 in
run.sh
invokes the API by posting a sample{ "message": "Hello World" }
in JSON.Line 53 in
template.yml
usestype: "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), }; };
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. Thetype: "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:
{"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.
Note that it has checked the tiny checkbox highlighted in the image. That’s what made the difference.