Share

How to access HTTP headers using AWS API Gateway and Lambda

 

Are you implementing custom authentication and need access to the Authorization header? Does your API present version information in a custom header? This article is for you.

Mapping Template

To provide information from the API Gateway's HTTP request to your Lambda function you will use what is called a Mapping Template. This is a JSON-like document that will be rendered to produce the contents of the event object. The template is made using the Velocity Template Language created by Apache. I'll explain a bit about the template language later, first let's just use it to get your header information into your Lambda.

Edit the Mapping Template in your Integration Request

In your AWS Console open up your API Gateway and find the method you want to provide headers. Locate the Integration Request box and click on it to open up these settings.

Open Integration Request

Find the Mapping Templates area of the Integration request and open it up. Add a new mapping template for the application/json Content-Type. You'll need to change the type in the combo box from "Input passthrough" to "Mapping Template". You will add a mapping template that will provide the HTTP headers along with the original request body to your Lambda.

Create the application/json Mapping Template

Enter this into the text area for the Mapping Template:

1
2
3
4
5
6
7
8
9
{
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

#end
}
}

Save the mapping template and now your Lambda function will recieve an event object with a headers object property. This property will contain all the HTTP headers that appeared in the API Gateway request.

Updating your Lambda

You can now access the HTTP headers through event.headers and the body of a POST or PUT method through event.body. The following simple Lambda handler shows how to log the values:

1
2
3
4
5
6
exports.handler = function(event, context) {
console.log('Request Headers:', event.headers);
console.log('Request Body', event.body);

context.succeed('Success');
};

Dissecting the Mapping Template

The mapping template has a lot going on inside it. I'll save the details of how it's generally used for another post, but I will explain what each line of the template does here.

1
"body" : $input.json('$'),

This line takes whatever was part of the original request body and maps it into the body property of the Lambda event object. This way if you're trying to use this in a POST or a PUT you will have access to the orginal request body in event.body. The function $input.json() is a function available in the AWS Velocity Template. The special '$' parameter tells it to pass the entire body instead of just a sub-path.

1
#foreach($param in $input.params().header.keySet())

This line iterates over each HTTP header in the request. It gets the headers from the $input.params() function and then provides the keySet() to the for loop to iterate over. These headers are assigned to the $param iterator variable.

1
"$param": "$util.escapeJavaScript($input.params().header.get($param))"

This line will be written once for each iteration of the foreach loop. It creates a JSON property for each $param, which is one of the HTTP header names. The value of the property is going to be the value of the HTTP header. You get this value using $input.params().header.get() and passing it in the key. The $util.escapeJavascript() function is used in case the header value contains a quote character that needs to be escaped.

1
#if($foreach.hasNext),#end

This #if statement checks to see if there will be another iteration of the for loop and prints a comma if there will be to keep the JSON valid.

1
#end

Finally, the foreach loop is ended with the #end statement.

Resources

I used the following resources from AWS and Apache to come up with this mapping template. You may find them useful in customizing the template presented here:

Thanks for reading!

Were you able to use the information in this article? Please let me know! I welcome any & all feedback. You can reach me at kennbbrodhagen@gmail.com or on Twitter @kennbrodhagen.

Interested in more?

Sign up for my mailing list. You'll get each new article and other announcements delivered to your inbox. I promise not to spam you. Unsubscribe any time you like.