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-namefor a path parameter namedparameter-nameas defined in the Method Request page.method.request.querystring.parameter-namefor a query string parameter namedparameter-nameas defined in the Method Request page.
I don't see either of these options even though I defined a query string.
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']
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/jsonin 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)
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
}
}
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.
The accepted answer worked fine for me, but expanding on gimenete's answer, I wanted a generic template I could use to pass through all query/path/header params (just as strings for now), and I came up the following template. I'm posting it here in case someone finds it useful:
#set($keys = [])
#foreach($key in $input.params().querystring.keySet())
#set($success = $keys.add($key))
#end
#foreach($key in $input.params().headers.keySet())
#if(!$keys.contains($key))
#set($success = $keys.add($key))
#end
#end
#foreach($key in $input.params().path.keySet())
#if(!$keys.contains($key))
#set($success = $keys.add($key))
#end
#end
{
#foreach($key in $keys)
"$key": "$util.escapeJavaScript($input.params($key))"#if($foreach.hasNext),#end
#end
}
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
As part of trying to answer one of my own questions here, I came across this trick.
In the API Gateway mapping template, use the following to give you the complete query string as sent by the HTTP client:
{
"querystring": "$input.params().querystring"
}
The advantage is that you don't have to limit yourself to a set of predefined mapped keys in your query string. Now you can accept any key-value pairs in the query string, if this is how you want to handle.
Note: According to this, only $input.params(x) is listed as a variable made available for the VTL template. It is possible that the internals might change and querystring may no longer be available.
Now you should be able to use the new proxy integration type for Lambda to automatically get the full request in standard shape, rather than configure mappings.
A lot of the answers here are great. But I wanted something a little simpler. I wanted something that will work with the "Hello World" sample for free. This means I wanted a simple produces a request body that matches the query string:
{
#foreach($param in $input.params().querystring.keySet())
"$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}
I think the top answer produces something more useful when building something real, but for getting a quick hello world running using the template from AWS this works great.
The following parameter-mapping example passes all parameters, including path, querystring and header, through to the integration endpoint via a JSON payload
#set($allParams = $input.params())
{
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
}
}
In effect, this mapping template outputs all the request parameters in the payload as outlined as follows:
{
"parameters" : {
"path" : {
"path_name" : "path_value",
...
}
"header" : {
"header_name" : "header_value",
...
}
'querystring" : {
"querystring_name" : "querystring_value",
...
}
}
}
Copied from the Amazon API Gateway Developer Guide
GET /user?name=bob
{
"name": "$input.params().querystring.get('name')"
}
GET /user/bob
{
"name": "$input.params('name')"
}
The query string is straight forward to parse in javascript in the lambda
for GET /user?name=bob
var name = event.params.querystring.name;
This doesn't solve the GET user/bob question though.
The Lambda function expects JSON input, therefore parsing the query string is needed. The solution is to change the query string to JSON using the Mapping Template.
I used it for C# .NET Core, so the expected input should be a JSON with "queryStringParameters" parameter.
Follow these 4 steps below to achieve that:
- Open the mapping template of your API Gateway resource and add new
application/jsoncontent-tyap:
Copy the template below, which parses the query string into JSON, and paste it into the mapping template:
{ "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end} }In the API Gateway, call your Lambda function and add the following query string (for the example):
param1=111¶m2=222¶m3=333The mapping template should create the JSON output below, which is the input for your Lambda function.
{ "queryStringParameters": {"param3":"333","param1":"111","param2":"222"} }You're done. From this point, your Lambda function's logic can use the query string parameters.
Good luck!
You can used Lambda as "Lambda Proxy Integration" ,ref this [https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html#api-gateway-proxy-integration-lambda-function-python] , options avalible to this lambda are
For Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables', and 'event.requestContext'
For Python Lambda event['headers']['parametername'] and so on
As @Jonathan's answer, after mark Use Lambda Proxy integration in Integration Request, in your source code you should implement as below format to by pass 502 Bad Gateway error.
NodeJS 8.10:
exports.handler = async (event, context, callback) => {
// TODO: You could get path, parameter, headers, body value from this
const { path, queryStringParameters, headers, body } = event;
const response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify({
path,
query: queryStringParameters,
headers,
body: JSON.parse(body)
}),
"isBase64Encoded": false
};
return response;
};
Don't forget deploy your resource at API Gateway before re-run your API. Response JSON just return which set in body is correct. So, you could get path, parameter, headers, body value from event
const { path, queryStringParameters, headers, body } = event;
After reading several of these answers, I used a combination of several in Aug of 2018 to retrieve the query string params through lambda for python 3.6.
First, I went to API Gateway -> My API -> resources (on the left) -> Integration Request. Down at the bottom, select Mapping Templates then for content type enter application/json.
Next, select the Method Request Passthrough template that Amazon provides and select save and deploy your API.
Then in, lambda event['params'] is how you access all of your parameters. For query string: event['params']['querystring']
来源:https://stackoverflow.com/questions/31329958/how-to-pass-a-querystring-or-route-parameter-to-aws-lambda-from-amazon-api-gatew


