How do I pass custom headers through API Gateway to a Lambda function using Lambda custom (non-proxy) integration?

Last updated: 2022-09-16

I want to configure an AWS Lambda function through custom (non-proxy) integration to process custom headers that are passed through my Amazon API Gateway API. How do I set that up?

Short description

By default, a Lambda function processes only the method request body it receives from an API Gateway API request. To pass custom headers from an API Gateway API to a Lambda function, use a body mapping template. The API sends the updated API request to a Lambda function to process the headers. Then, the Lambda function returns one or more header values from the original API request.

Resolution

Configure the required AWS Identity and Access Management (IAM) permissions

Follow the instructions in Control access to an API with IAM permissions.

For testing this procedure, you can create an IAM role and attach the following AWS managed policies:

  • AmazonAPIGatewayInvokeFullAccess
  • AmazonAPIGatewayPushToCloudWatchLogs

Create a Lambda function to handle custom headers from your API Gateway API

1.    Open the Lambda console.

2.    Choose Create function. The Create function page opens with the Author from scratch option selected.

3.    In the Basic information pane, do the following:
For Function name, enter a name that describes your function's purpose. For example: CustomHeaders.
For Runtime, choose Node.js 14.x.

4.    Under Permissions, expand Change default execution role.

5.    Choose Use an existing role. A dropdown list of existing roles appears.

6.    For Existing role, choose the Lambda execution role that you created previously.

7.    Choose Create function.

8.    On the Code source pane, replace the code in the editor pane (index.js) with the following:

exports.handler = (event, context, callback) => {
// TODO implement
callback(null, "This message header was processed by Amazon " +event.headers["header1"]);
};

9.    Choose Save.

For more information, see Building Lambda functions with Node.js.

Create an API Gateway REST API

1.    Open the API Gateway console.

2.    Choose Create API.

-or-

(If this is your first time using API Gateway) A page that introduces you to the features of the service appears. Under REST API, choose Build. When the Create Example API popup appears, choose OK.

3.    For Choose an API type, in the REST API pane, choose Build.

4.    Under Create new API, choose New API.

5.    Under Settings, do the following:
For API name, enter a name that describes your API's purpose. For example: SendtoLambda.
(Optional) For Description, enter a short description your API's purpose.
For Endpoint Type, choose Regional.

6.    Choose Create API.

Configure your API's integration point and body mapping template

1.    In the API Gateway console, choose the name of the API that you created in the previous step. Your API's Resources page opens.

2.    On the Resources page, choose Actions. Then, choose Create Resource.

3.    In the New Child Resource pane, do the following:
For Resource Name, enter a name that describes the resource. For example: HeadersResource.
Choose Create Resource.

4.    Choose Actions. Then, choose Create Method.

5.    From the dropdown list under /headersresource, choose POST. Then, choose the check mark icon.

6.    On the /headersresource - POST - Setup page, do the following:
For Integration type, choose Lambda Function.
For Lambda Region, choose the AWS Region that hosts your function.
For Lambda Function, enter your function's name.
Choose Save. An Add Permission to Lambda Function popup appears.
In the popup, choose OK.

7.    On the /headersresource - POST - Method Execution page, choose Integration Request.

8.    On the /headersresource - POST - Integration Request page, do the following:
Expand Mapping Templates.
For Request body passthrough, choose When there are no templates defined (recommended).
Choose Add mapping template.
For Content-Type, enter application/json. Then, choose the check mark icon.

9.    In the mapping template editor, enter the following:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))"
    #if($foreach.hasNext),#end
    #end
  }
}

10.    Choose Save.

Deploy your API to a new stage

1.    Follow the instructions in Deploy a REST API to a stage. For more information, see Setting up a stage using the API Gateway console.

2.    In the Stage Editor pane, copy the Invoke URL to your clipboard.

REST API Invoke URL example

https://1a2bc3d456.execute-api.region.amazonaws.com/test

Test your setup

To confirm that message headers are being processed by your API and Lambda function, run the following curl command:

Important: Replace https://restApiId.execute-api.region.amazonaws.com/stageName with your API's invoke URL.

curl -H "Content-Type: application/json" -H "header1: API Gateway and AWS Lambda" -X POST -d "{\"API_body\": \"This is the body\"}" https://restApiId.execute-api.region.amazonaws.com/stageName/headersresource

Example output

"This message header was processed by Amazon API Gateway and AWS Lambda"

Note: To install curl on Windows, see Downloads on the Git website. For more information about curl, see the curl project website.