如何将查询string或路由参数从Amazon API Gateway传递到AWS Lambda
例如,如果我们想使用
GET /user?name=bob
要么
GET /user/bob
如何将这两个例子作为parameter passing给Lambda函数?
我在文档中看到了有关设置“映射自”的一些信息,但在API网关控制台中找不到该设置。
-
method.request.path.parameter-name
用于名为parameter-name
的path参数,如方法请求页面中所定义。 -
method.request.querystring.parameter-name
用于名为parameter-name
的查询string参数,如方法请求页面中所定义。
即使我定义了一个查询string,我也没有看到这两个选项。
截至2017年9月,您不再需要configuration映射来访问请求主体。
您只需在资源下的“集成请求”下选中“使用Lambda代理集成”即可。
然后,您将能够像访问那样访问查询参数,path参数和标题
event['pathParameters']['param1'] event["queryStringParameters"]['queryparam1'] event['requestContext']['identity']['userAgent'] event['requestContext']['identity']['sourceIP']
得到这个工作的步骤是:
在API网关控制台中…
- 去
Resources -> Integration Request
- 点击模板下拉列表中的加号或编辑图标(奇怪,我知道,因为模板字段已经打开,这里的button看起来灰色)
- 在content-type字段中显式键入
application/json
,即使它显示一个默认值(如果你不这样做,它不会保存,不会给你一个错误信息) -
把它放在input映射
{ "name": "$input.params('name')" }
-
点击模板下拉框旁边的checkbox(我假设这是最后保存的)
我已经使用此映射模板为Lambda事件提供Body,Headers,Method,Path和URL查询string参数。 我写了一篇博客文章更详细地解释了模板: http : //kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-网关/
您可以使用以下映射模板:
{ "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 } }
现在,AWS上的API网关控制台中包含一个下拉模板。
对于您的API,请单击资源名称,然后单击GET
展开“正文映射模板”
input
应用程序/ JSON
对于Content-Type(必须明确input)并单击打勾
一个新的窗口将打开“生成模板”和一个下拉菜单(见图)。
select
方法请求传递
然后点击保存
要访问任何variables,只需使用以下语法(这是Python)例如URL:
https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5
你可以得到如下的variables:
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'])
所以没有必要明确地命名或映射你想要的每个variables。
接受的答案对我来说工作得很好,但扩展了gimenete的答案,我想要一个通用的模板,我可以用来通过所有查询/path/头部参数(就像现在的string),我想出了以下模板。 我在这里发布它,以防有人发现它有用:
#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 }
为了将parameter passing给您的lambda函数,您需要在API网关请求和您的lambda函数之间创build一个映射。 映射在所选API网关资源的Integration Request
– > Mapping templates
部分完成。
创build一个application/json
types的映射,然后在右边你将编辑(点击铅笔)模板。
映射模板实际上是一个Velocity模板,您可以在其中使用ifs,loop,当然还有打印variables。 该模板具有这些variables注入的地方,您可以单独访问查询string参数,请求标头等。 用下面的代码你可以重新创build整个查询string:
{ "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('$') }
注意:点击检查符号保存模板。 您可以使用资源中的“testing”buttontesting您的更改。 但是为了在AWS控制台中testing查询string参数,您需要在资源的“ Method Request
部分中定义参数名称。
注意:请查看Velocity用户指南以获取有关Velocity模板语言的更多信息。
然后在您的lambda模板中,您可以执行以下操作来parsing查询string:
var query = require('querystring').parse(event.querystring) // access parameters with query['foo'] or query.foo
作为回答我自己的一个问题的一部分,我遇到了这个窍门。
在API网关映射模板中,使用以下命令为您提供由HTTP客户端发送的完整查询string:
{ "querystring": "$input.params().querystring" }
好处是,您不必将自己限制在查询string中的一组预定义的映射键。 现在,您可以接受查询string中的任何键值对,如果这是您想要处理的。
注意:据此,只有$input.params(x)
被列为可用于VTL模板的variables。 内部可能会改变, querystring
可能不再可用。
现在,您应该能够使用Lambda的新代理集成types来自动获取标准形状的完整请求,而不是configuration映射。
请参阅: http : //docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-代理资源
这里的很多答案都很棒。 但是我想要一些简单的东西。 我想要一些可以免费使用“Hello World”示例的东西。 这意味着我想要一个简单的生成与查询string匹配的请求主体:
{ #foreach($param in $input.params().querystring.keySet()) "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end #end }
我认为最好的答案在构build真实的东西的时候会产生更有用的东西,但是为了使用AWS中的模板运行一个快速的hello world,这非常有效。
以下参数映射示例将所有参数(包括path,查询string和标题)通过JSON有效内容传递到集成端点
#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 } }
实际上,这个映射模板输出有效负载中的所有请求参数,如下所述:
{ "parameters" : { "path" : { "path_name" : "path_value", ... } "header" : { "header_name" : "header_value", ... } 'querystring" : { "querystring_name" : "querystring_value", ... } } }
从“ Amazon API网关开发人员指南”复制
查询string是直接parsing在lambda中的JavaScript
GET / user?name = bob
var name = event.params.querystring.name;
这并不解决GET用户/鲍勃问题。
如果您正在使用JAVA作为您的Lambda函数,则可以使用Lambada Framework来为您处理这些东西。