例如,如果我们想使用
GET /user?name=bob
或者
GET /user/bob
您如何将这两个示例作为参数传递给 Lambda 函数?
我在文档中看到了有关设置“映射自”的内容,但在 API Gateway 控制台中找不到该设置。
method.request.path.parameter-name 用于在方法请求页面中定义的名为 parameter-name 的路径参数。
method.request.querystring.parameter-name 用于在方法请求页面中定义的名为 parameter-name 的查询字符串参数。
即使我定义了查询字符串,我也看不到这些选项中的任何一个。
自 2017 年 9 月起,您不再需要配置映射来访问请求正文。
您需要做的就是在资源下的集成请求下检查“使用 Lambda 代理集成”。
https://i.stack.imgur.com/P3ctm.png
然后,您将能够像这样访问查询参数、路径参数和标题
event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
使这项工作的步骤是:
在 API 网关控制台中...
转到资源-> 集成请求单击模板下拉列表旁边的加号或编辑图标(我知道,因为模板字段已经打开并且此处的按钮看起来是灰色的)即使在内容类型字段中显式键入 application/json它显示一个默认值(如果你不这样做,它不会保存,也不会给你一个错误消息)把它放在输入映射中 { "name": "$input.params('name')" } 点击模板下拉列表旁边的复选框(我假设这是最终保存它的内容)
我已使用此映射模板为 Lambda 事件提供正文、标题、方法、路径和 URL 查询字符串参数。我写了一篇博文更详细地解释了该模板:http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/
这是您可以使用的映射模板:
{
"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
}
}
deploy
api。一旦我使用新映射部署了 api,它就可以正常工作了。万分感谢。
如今,AWS 上的 API Gateway 控制台中包含一个下拉模板。
对于您的 API,单击资源名称...然后 GET
展开“身体映射模板”
输入
应用程序/json
对于 Content-Type (必须明确输入)并单击对勾
将打开一个带有“生成模板”字样的新窗口和一个下拉菜单(见图)。
选择
方法请求直通
https://i.stack.imgur.com/rwn8I.png
然后点击保存
要访问任何变量,只需使用以下语法(这是 Python),例如 URL:
https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5
您可以按如下方式获取变量:
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'])
因此,无需显式命名或映射您想要的每个变量。
为了将参数传递给您的 lambda 函数,您需要在 API Gateway 请求和您的 lambda 函数之间创建一个映射。映射在 Integration Request
-> 中完成。所选 API Gateway 资源的 Mapping templates
部分。
创建类型为 application/json
的映射,然后在右侧编辑(单击铅笔)模板。
映射模板实际上是一个 Velocity 模板,您可以在其中使用 ifs、循环,当然还可以在其上打印变量。该模板有 these variables injected,您可以在其中单独访问查询字符串参数、请求标头等。使用以下代码,您可以重新创建整个查询字符串:
{
"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('$')
}
注意:单击复选符号以保存模板。您可以使用资源中的“测试”按钮测试您的更改。但为了在 AWS 控制台中测试查询字符串参数,您需要在资源的 Method Request
部分中定义参数名称。
注意:查看 Velocity User Guide 了解有关 Velocity 模板语言的更多信息。
然后在您的 lambda 模板中,您可以执行以下操作来解析查询字符串:
var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
Actions>Deploy API
(我浪费了我的时间忘记这个......)。关联的 lambda arn 将在部署后立即进行更改。您可以在Stages > #stage (like: prod) > Deployment History
中查看。
接受的答案对我来说很好,但是扩展了 gimenete 的答案,我想要一个通用模板,我可以使用它来传递所有查询/路径/标题参数(就像现在的字符串一样),我想出了以下模板。我把它贴在这里以防有人发现它有用:
#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
}
作为尝试回答我自己的一个问题 here 的一部分,我遇到了这个技巧。
在 API Gateway 映射模板中,使用以下内容为您提供 HTTP 客户端发送的完整查询字符串:
{
"querystring": "$input.params().querystring"
}
优点是您不必将自己限制在查询字符串中的一组预定义映射键。现在,您可以接受查询字符串中的任何键值对,如果这是您想要处理的方式。
注意:根据 this,只有 $input.params(x)
被列为可用于 VTL 模板的变量。内部结构可能会发生变化,并且 querystring
可能不再可用。
现在您应该能够使用 Lambda 的新代理集成类型来自动获取标准格式的完整请求,而不是配置映射。
获取 /user?name=bob
{
"name": "$input.params().querystring.get('name')"
}
获取/用户/鲍勃
{
"name": "$input.params('name')"
}
这里的很多答案都很棒。但我想要一些更简单的东西。我想要一些可以免费使用“Hello World”示例的东西。这意味着我想要一个简单的生成与查询字符串匹配的请求正文:
{
#foreach($param in $input.params().querystring.keySet())
"$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}
我认为最重要的答案在构建真实的东西时会产生更有用的东西,但是为了使用 AWS 的模板快速运行你好世界,这非常有用。
查询字符串可以直接在 lambda 中用 javascript 解析
对于 GET /user?name=bob
var name = event.queryStringParameters.name;
不过,这并不能解决 GET 用户/鲍勃问题。
event.queryStringParameters.name
以下参数映射示例通过 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 Gateway Developer Guide
要获取查询参数,您可以像这样在 queryStringParameters
对象中获取它们
const name = event.queryStringParameters.name;
第二个是一个干净的 URL。如果您的路径是 /user/{name}
,则要从 pathParameters
对象中获取值,如下所示
const name = event.pathParameters.name;
pathParameters
对象或在本例中是 name
?还是 queryStringParameters
?
正如@Jonathan 的回答,在集成请求中标记使用 Lambda 代理集成后,在您的源代码中,您应该按照以下格式实现以绕过 502 Bad Gateway 错误。
节点JS 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;
};
在重新运行您的 API 之前,不要忘记在 API Gateway 上部署您的资源。响应 JSON 只返回正文中的哪个集合是正确的。因此,您可以从事件中获取路径、参数、标题、正文值
const { 路径,queryStringParameters,标题,正文 } = 事件;
Python 3.8 和 boto3 v1.16v - 2020 年 12 月
要配置路由,您必须配置 API Gateway 以接受路由。否则,除了基本路线之外,其他一切都会以 {missing auth token} 或其他东西结束......
一旦你配置 API Gateway 接受路由,确保你启用了 lambda 代理,这样事情会更好地工作,
访问路线,
new_route = event['path'] # /{some_url}
访问查询参数
query_param = event['queryStringParameters'][{query_key}]
Lambda 函数需要 JSON 输入,因此需要解析查询字符串。解决方案是使用映射模板将查询字符串更改为 JSON。我将它用于 C# .NET Core,因此预期的输入应该是带有“queryStringParameters”参数的 JSON。请按照以下 4 个步骤来实现:
打开 API Gateway 资源的映射模板并添加新的 application/json content-tyap:
https://i.stack.imgur.com/UnQZc.png
复制下面的模板,它将查询字符串解析为 JSON,并将其粘贴到映射模板中: { "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($ foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end} } 在 API Gateway 中,调用您的 Lambda 函数并添加以下查询字符串 (例如): param1=111¶m2=222¶m3=333 映射模板应该在下面创建 JSON 输出,这是您的 Lambda 函数的输入。 { "queryStringParameters": {"param3":"333","param1":"111","param2":"222"} } 你完成了。从此时起,您的 Lambda 函数逻辑可以使用查询字符串参数。祝你好运!
exports.handler = async (event) => {
let query = event.queryStringParameters;
console.log(`id: ${query.id}`);
const response = {
statusCode: 200,
body: "Hi",
};
return response;
};
您可以将 Lambda 用作 "Lambda 代理集成" ,参考此 [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] ,此 lambda 可用的选项是
对于 Nodejs Lambda 'event.headers'、'event.pathParameters'、'event.body'、'event.stageVariables' 和 'event.requestContext'
对于 Python Lambda 事件['headers']['parametername'] 等等
我的目标是传递一个类似于以下内容的查询字符串:
protodb?sql=select * from protodb.prototab
通过来自 API 网关的 URL 到 Node.js 12 Lambda 函数。我尝试了其他答案中的一些想法,但真的想以最原生的 API 网关 UI 方式做一些事情,所以我想出了这个对我有用的方法(截至 2020 年 12 月的 API 网关 UI) :
在给定 API 的 API Gateway 控制台上的资源下,选择 get 方法。然后选择它的集成请求并在页面顶部填写 lambda 函数的数据。
滚动到底部并打开映射模板部分。如果没有定义模板(推荐),请选择 Request Body Passthrough。
单击添加映射模板并使用 application/json 的内容类型创建一个,然后单击复选标记按钮。
对于该映射模板,在下拉列表中选择 Method Request passthrough 以生成模板,该模板将使用 AWS 传递所有内容的一般方式填充其下方的文本框。
点击保存按钮。
现在,当我测试它时,我无法在 Lambda 函数中的节点 JS 下将参数作为 event.sql 通过。事实证明,当 API 网关将 URL sql 查询参数发送到 Lambda 函数时,它通过 Node.js 为:
var insql = event.params.querystring.sql;
所以我花了一些时间的技巧是使用 JSON.stringify 来显示完整的事件堆栈,然后通过这些部分向下工作,以便能够从查询字符串中提取 sql 参数。
所以基本上你可以在 API 网关中使用默认的直通功能,诀窍是当你在 Lambda 函数中时如何传递参数。
对我有用的方法是
转到集成请求单击 URL 查询字符串参数单击在名称字段中添加查询字符串在 Mapped From 字段中输入查询名称,即“名称”,输入“method.request.querystring.name”
在阅读了其中几个答案后,我在 2018 年 8 月结合使用了几个答案,通过 lambda for python 3.6 检索查询字符串参数。
首先,我去了 API Gateway ->我的 API ->资源(在左侧)->集成请求。在底部,选择映射模板,然后为内容类型输入 application/json
。
接下来,选择 Amazon 提供的 Method Request Passthrough 模板,然后选择 save and deploy your API。
然后,lambda event['params']
是您访问所有参数的方式。对于查询字符串:event['params']['querystring']
不定期副业成功案例分享