How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway
Solution 1
As of September 2017, you no longer have to configure mappings to access the request body.
All you need to do is check, "Use Lambda Proxy integration", under Integration Request, under the resource.
You'll then be able to access query parameters, path parameters and headers like so
event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Solution 2
The steps to get this working are:
Within the API Gateway Console ...
- go to
Resources -> Integration Request
- click on the plus or edit icon next to templates dropdown (odd I know since the template field is already open and the button here looks greyed out)
- Explicitly type
application/json
in the content-type field even though it shows a default (if you don't do this it will not save and will not give you an error message) put this in the input mapping
{ "name": "$input.params('name')" }
click on the check box next to the templates dropdown (I'm assuming this is what finally saves it)
Solution 3
I have used this mapping template to provide Body, Headers, Method, Path, and URL Query String Parameters to the Lambda event. I wrote a blog post explaining the template in more detail: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/
Here is the Mapping Template you can use:
{
"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
},
"queryParams": {
#foreach($param in $input.params().querystring.keySet())
"$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
},
"pathParams": {
#foreach($param in $input.params().path.keySet())
"$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end
#end
}
}
Solution 4
These days a drop-down template is included in the API Gateway Console on AWS.
For your API, click on the resource name... then GET
Expand "Body Mapping Templates"
Type in
application/json
for Content-Type (must be explicitly typed out) and click the tick
A new window will open with the words "Generate template" and a dropdown (see image).
Select
Method Request passthrough
Then click save
To access any variables, just use the following syntax (this is Python) e.g. URL:
https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5
You can get variables as follows:
from __future__ import print_function
import boto3
import json
print('Loading function')
def lambda_handler(event, context):
print(event['params']['querystring']['token'])
print(event['params']['querystring']['uid'])
So there is no need to explicitly name or map each variable you desire.
Solution 5
In order to pass parameters to your lambda function you need to create a mapping between the API Gateway request and your lambda function. The mapping is done in the Integration Request
-> Mapping templates
section of the selected API Gateway resource.
Create a mapping of type application/json
, then on the right you will edit (click the pencil) the template.
A mapping template is actually a Velocity template where you can use ifs, loops and of course print variables on it. The template has these variables injected where you can access querystring parameters, request headers, etc. individually. With the following code you can re-create the whole querystring:
{
"querystring" : "#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0)&#end$util.urlEncode($key)=$util.urlEncode($input.params().querystring.get($key))#end",
"body" : $input.json('$')
}
Note: click on the check symbol to save the template. You can test your changes with the "test" button in your resource. But in order to test querystring parameters in the AWS console you will need to define the parameter names in the Method Request
section of your resource.
Note: check the Velocity User Guide for more information about the Velocity templating language.
Then in your lambda template you can do the following to get the querystring parsed:
var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
MonkeyBonkey
CTO of Pictorious.com, a mobile app for turning photo sharing into a fun meme-game.
Updated on December 27, 2021Comments
-
MonkeyBonkey over 2 years
for instance if we want to use
GET /user?name=bob
or
GET /user/bob
How would you pass both of these examples as a parameter to the Lambda function?
I saw something about setting a "mapped from" in the documentation, but I can't find that setting in the API Gateway console.
method.request.path.parameter-name
for a path parameter namedparameter-name
as defined in the Method Request page.method.request.querystring.parameter-name
for a query string parameter namedparameter-name
as defined in the Method Request page.
I don't see either of these options even though I defined a query string.
-
Lucas almost 9 yearsDid you ever get this to send through URL parameters in URLs like /user/bob where the route was /user/{username}? I have tried all kinds of permutations, but have been unable to work that out.
-
Vikas Jangra about 8 yearsAmazing! I was struggling with passing things along generically to my handler. Best answer here.
-
Parthapratim Neog about 8 yearsI did this, but I am not getting anything yet. Its showing Undefined. How are we supposed to sent the Parameters in the URL? and do we need specify the variable name in the url like in a normal GET url scenario? Please help me out with this.
-
Parthapratim Neog about 8 yearsNevermind I got the result. The problem was, I added the mapping and just saved it, and did not
deploy
the api once again. Once I deployed the api with the new mapping, it worked just fine. Thanks a ton. -
loretoparisi almost 8 yearsThis is the best solution. Please remember to do
Actions>Deploy API
then (I wasted my time forgetting this...). The associated lambda arn will take the change immediately after the deployment. You can check it inStages > #stage (like: prod) > Deployment History
. -
matsev over 7 years@shashu10 See my answer
-
Gustavo Straube over 7 yearsI'm not sure why, but the proxy integration usually doesn't work for me. I had to remove it from the latest APIs I've created.
-
Stephen Tetreault over 7 yearssame ^ furthermore I've had CORS issues with API Gateway. Following along with AWS docs I was not able to get CORS working. However I found an old Medium article from mid-late 2015 which had a manual way of setting up CORS and that worked.
-
Tom Saleeba almost 7 yearsThis still works as of May 2017 but it returns the JS object that API Gateway creates for you rather than the actual query string. This is annoying for me because I'm trying to parse the query string to turn repeated params into an array.
-
AaronBaker over 6 yearsThis is a great tip. But, keep in mind that turning on Lambda Proxy Integration could cause a "Malformed Lambda Proxy Response" error. Here's how to fix it: stackoverflow.com/questions/43708017/…
-
user3685427 over 6 yearsI can't begin to tell you how useful your blog is. I found the "eturn-html-from-aws-api-gateway" post first and followed it, because it's exactly what I needed. Now I need to pass some parameters in to the function and modify the html based on that - and again you're the only one with a real guide! All the other guides I've found seem to miss the point.
-
Neo over 5 yearsits event.queryStringParameters.name
-
Matt Fletcher over 5 yearsFab, I wanted to be able to use the same function for both POST (with JSON body) requests and GET with query strings. Works a dream. Thanks!
-
nxmohamad almost 5 years@benv is this the full template?
-
Anders Kitson almost 4 yearsI had to do
event.queryStringParameters.name
-
Stefan Sprenger about 2 yearsBoth undefined for me
-
chaulap about 2 yearsWhich is undefined the
pathParameters
object or in this case thename
? Or is it thequeryStringParameters
?