如何将查询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网关控制台中…

  1. Resources -> Integration Request
  2. 点击模板下拉列表中的加号或编辑图标(奇怪,我知道,因为模板字段已经打开,这里的button看起来灰色)
  3. 在content-type字段中显式键入application/json ,即使它显示一个默认值(如果你不这样做,它不会保存,不会给你一个错误信息)
  4. 把它放在input映射{ "name": "$input.params('name')" }

  5. 点击模板下拉框旁边的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/jsontypes的映射,然后在右边你将编辑(点击铅笔)模板。

映射模板实际上是一个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来为您处理这些东西。