ChatGPT解决这个技术问题 Extra ChatGPT

如何将查询字符串或路由参数从 Amazon API Gateway 传递到 AWS Lambda

例如,如果我们想使用

GET /user?name=bob

或者

GET /user/bob

您如何将这两个示例作为参数传递给 Lambda 函数?

我在文档中看到了有关设置“映射自”的内容,但在 API Gateway 控制台中找不到该设置。

method.request.path.parameter-name 用于在方法请求页面中定义的名为 parameter-name 的路径参数。

method.request.querystring.parameter-name 用于在方法请求页面中定义的名为 parameter-name 的查询字符串参数。

即使我定义了查询字符串,我也看不到这些选项中的任何一个。


J
Jonathan

自 2017 年 9 月起,您不再需要配置映射来访问请求正文。

您需要做的就是在资源下的集成请求下检查“使用 Lambda 代理集成”。

https://i.stack.imgur.com/P3ctm.png

然后,您将能够像这样访问查询参数、路径参数和标题

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']

这是一个很好的提示。但是,请记住,打开 Lambda 代理集成可能会导致“格式错误的 Lambda 代理响应”错误。解决方法如下:stackoverflow.com/questions/43708017/…
C
ColinE

使这项工作的步骤是:

在 API 网关控制台中...

转到资源-> 集成请求单击模板下拉列表旁边的加号或编辑图标(我知道,因为模板字段已经打开并且此处的按钮看起来是灰色的)即使在内容类型字段中显式键入 application/json它显示一个默认值(如果你不这样做,它不会保存,也不会给你一个错误消息)把它放在输入映射中 { "name": "$input.params('name')" } 点击模板下拉列表旁边的复选框(我假设这是最终保存它的内容)


你有没有让这个通过 URL 中的 URL 参数发送,比如 /user/bob,其中路由是 /user/{username}?我尝试了各种排列,但一直无法解决。
k
kennbrodhagen

我已使用此映射模板为 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
  }  
}

惊人!我一直在努力将事情一般地传递给我的处理程序。最佳答案在这里。
我这样做了,但我还没有得到任何东西。它显示未定义。我们应该如何在 URL 中发送参数?我们是否需要像在普通的 GET url 场景中一样在 url 中指定变量名?这个你能帮我吗。
没关系,我得到了结果。问题是,我添加了映射并保存了它,并没有再次deploy api。一旦我使用新映射部署了 api,它就可以正常工作了。万分感谢。
@shashu10 看我的回答
我无法开始告诉你你的博客有多有用。我首先找到了“eturn-html-from-aws-api-gateway”帖子并关注了它,因为它正是我所需要的。现在我需要将一些参数传递给函数并根据这些参数修改 html - 再说一次,你是唯一一个有真正指南的人!我发现的所有其他指南似乎都没有抓住重点。
D
D2TheC

如今,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'])

因此,无需显式命名或映射您想要的每个变量。


a
ankon

为了将参数传递给您的 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中查看。
B
BenV

接受的答案对我来说很好,但是扩展了 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
}

Fab,我希望能够对 POST(带有 JSON 正文)请求和带有查询字符串的 GET 使用相同的函数。做梦。谢谢!
@benv 这是完整的模板吗?
C
Community

作为尝试回答我自己的一个问题 here 的一部分,我遇到了这个技巧。

在 API Gateway 映射模板中,使用以下内容为您提供 HTTP 客户端发送的完整查询字符串:

{
    "querystring": "$input.params().querystring"
}

优点是您不必将自己限制在查询字符串中的一组预定义映射键。现在,您可以接受查询字符串中的任何键值对,如果这是您想要处理的方式。

注意:根据 this,只有 $input.params(x) 被列为可用于 VTL 模板的变量。内部结构可能会发生变化,并且 querystring 可能不再可用。


这在 2017 年 5 月仍然有效,但它返回 API Gateway 为您创建的 JS 对象,而不是实际的查询字符串。这对我来说很烦人,因为我试图解析查询字符串以将重复的参数转换为数组。
j
jackko

现在您应该能够使用 Lambda 的新代理集成类型来自动获取标准格式的完整请求,而不是配置映射。

见:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-proxy-resource


我不知道为什么,但代理集成通常对我不起作用。我必须从我创建的最新 API 中删除它。
同样 ^ 此外,我在 API 网关方面遇到了 CORS 问题。跟随 AWS 文档,我无法让 CORS 工作。但是,我发现了一篇 2015 年中后期的旧 Medium 文章,其中有手动设置 CORS 的方法,并且有效。
D
Dmitry Grinko

获取 /user?name=bob

{
    "name": "$input.params().querystring.get('name')"
}

获取/用户/鲍勃

{
    "name": "$input.params('name')"
}

K
KrisTC

这里的很多答案都很棒。但我想要一些更简单的东西。我想要一些可以免费使用“Hello World”示例的东西。这意味着我想要一个简单的生成与查询字符串匹配的请求正文:

{
#foreach($param in $input.params().querystring.keySet())
  "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}

我认为最重要的答案在构建真实的东西时会产生更有用的东西,但是为了使用 AWS 的模板快速运行你好世界,这非常有用。


J
Jerónimo Ekerdt

查询字符串可以直接在 lambda 中用 javascript 解析

对于 GET /user?name=bob

 var name = event.queryStringParameters.name;

不过,这并不能解决 GET 用户/鲍勃问题。


它的 event.queryStringParameters.name
我必须做event.queryStringParameters.name
m
matsev

以下参数映射示例通过 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


c
chaulap

要获取查询参数,您可以像这样在 queryStringParameters 对象中获取它们

const name = event.queryStringParameters.name;

第二个是一个干净的 URL。如果您的路径是 /user/{name},则要从 pathParameters 对象中获取值,如下所示

const name = event.pathParameters.name;

对我来说都是未定义的
哪个是未定义的 pathParameters 对象或在本例中是 name?还是 queryStringParameters
L
Long Nguyen

正如@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,标题,正文 } = 事件;


D
Dev-2019

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}]

L
Lior Kirshner

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 函数逻辑可以使用查询字符串参数。祝你好运!


O
Oded Breiner
exports.handler = async (event) => {
    let query = event.queryStringParameters;
    console.log(`id: ${query.id}`);
    const response = {
        statusCode: 200,
        body: "Hi",
    };
    return response;
};

R
RajDev

您可以将 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'] 等等


D
Dharman

我的目标是传递一个类似于以下内容的查询字符串:

 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 函数中时如何传递参数。


w
waw waw

对我有用的方法是

转到集成请求单击 URL 查询字符串参数单击在名称字段中添加查询字符串在 Mapped From 字段中输入查询名称,即“名称”,输入“method.request.querystring.name”


J
Jghorton14

在阅读了其中几个答案后,我在 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']


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅