438

例如,如果我们想使用

GET /user?name=bob

或者

GET /user/bob

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

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

  • method.request.path.parameter-nameparameter-name对于在“方法请求”页面中定义的路径参数。
  • method.request.querystring.parameter-nameparameter-name对于在“方法请求”页面中定义的查询字符串参数。

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

4

22 回答 22

439

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

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

在此处输入图像描述

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

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
于 2017-09-08T10:19:04.203 回答
232

使这项工作的步骤是:

在 API 网关控制台中...

  1. Resources -> Integration Request
  2. 单击模板下拉列表旁边的加号或编辑图标(我知道,因为模板字段已经打开并且此处的按钮看起来是灰色的)
  3. 明确输入application/json内容类型字段,即使它显示默认值(如果您不这样做,它将不会保存并且不会给您错误消息)
  4. 把它放在输入映射中{ "name": "$input.params('name')" }

  5. 单击模板下拉列表旁边的复选框(我假设这是最终保存它的原因)

于 2015-07-10T15:48:07.013 回答
150

我已使用此映射模板为 Lambda 事件提供正文、标题、方法、路径和 URL 查询字符串参数。我写了一篇博客文章更详细地解释了模板: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
  }  
}
于 2015-12-07T01:26:59.567 回答
44

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

enter image description here

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.

于 2016-04-19T11:48:11.830 回答
28

为了将参数传递给您的 lambda 函数,您需要在 API Gateway 请求和您的 lambda 函数之间创建一个映射。映射在所选 API Gateway 资源的Integration Request->Mapping templates部分中完成。

创建类型的映射application/json,然后在右侧编辑(单击铅笔)模板。

映射模板实际上是一个 Velocity 模板,您可以在其中使用 ifs、循环,当然还可以在其上打印变量。模板注入了这些变量,您可以在其中单独访问查询字符串参数、请求标头等。使用以下代码,您可以重新创建整个查询字符串:

{
    "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 用户指南以获取有关 Velocity 模板语言的更多信息。

然后在您的 lambda 模板中,您可以执行以下操作来解析查询字符串:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
于 2015-10-15T08:15:05.337 回答
26

接受的答案对我来说很好,但是扩展了 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
}
于 2015-10-18T15:53:36.743 回答
20

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

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

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

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

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

于 2015-08-06T13:32:46.947 回答
14

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

请参阅:http ://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-代理资源

于 2016-09-27T17:01:32.243 回答
12

获取 /user?name=bob

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

获取/用户/鲍勃

{
    "name": "$input.params('name')"
}
于 2017-11-19T21:44:36.050 回答
8

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

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

我认为最重要的答案在构建真实的东西时会产生更有用的东西,但是对于使用 AWS 的模板运行一个快速的 hello world 来说效果很好。

于 2016-05-13T11:04:21.057 回答
6

以下参数映射示例通过 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 开发人员指南

于 2016-08-21T20:28:37.643 回答
6

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

对于 GET /user?name=bob

 var name = event.queryStringParameters.name;

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

于 2016-06-13T01:57:41.440 回答
2

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

const name = event.queryStringParameters.name;

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

const name = event.pathParameters.name;
于 2021-12-27T08:54:57.270 回答
2

正如@Jonathan 的回答,在Integration Request中标记Use Lambda Proxy integration之后,在您的源代码中,您应该按照以下格式实现以绕过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,标题,正文 } = 事件;

于 2018-08-31T01:38:13.537 回答
2

带有 boto3 v1.16v 的 Python 3.8 - 2020 年 12 月

要配置路由,您必须配置 API Gateway 以接受路由。否则,除了基本路线之外,其他一切都会以 {missing auth token} 或其他东西结束......

一旦你配置 API Gateway 接受路由,确保你启用了 lambda 代理,这样事情会更好,

访问路线,

new_route = event['path'] # /{some_url}

访问查询参数

query_param = event['queryStringParameters'][{query_key}]
于 2020-12-29T12:57:53.983 回答
1

Lambda 函数需要 JSON 输入,因此需要解析查询字符串。解决方案是使用映射模板将查询字符串更改为 JSON。
我将它用于 C# .NET Core,因此预期的输入应该是带有“queryStringParameters”参数的 JSON。
请按照以下 4 个步骤来实现:

  1. 打开 API Gateway 资源的映射模板并添加新application/json的 content-tyap:

API 网关映射模板

  1. 复制下面的模板,它将查询字符串解析为 JSON,并将其粘贴到映射模板中:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. 在 API Gateway 中,调用您的 Lambda 函数并添加以下查询字符串(例如):param1=111&param2=222&param3=333

  3. 映射模板应在下面创建 JSON 输出,这是您的 Lambda 函数的输入

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. 你完成了。从此时起,您的 Lambda 函数逻辑可以使用查询字符串参数。
    祝你好运!

于 2018-09-22T21:09:34.713 回答
1
exports.handler = async (event) => {
    let query = event.queryStringParameters;
    console.log(`id: ${query.id}`);
    const response = {
        statusCode: 200,
        body: "Hi",
    };
    return response;
};
于 2020-06-28T06:54:05.243 回答
0

对我有用的方法是

  1. 转到集成请求
  2. 点击 URL 查询字符串参数
  3. 单击添加查询字符串
  4. 在名称字段中输入查询名称,这里是“名称”
  5. 在 Mapped From 字段中,输入“method.request.querystring.name”
于 2020-12-19T23:06:32.493 回答
0

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

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

于 2020-12-15T22:00:23.707 回答
0

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

于 2018-01-09T18:06:30.017 回答
-1

在阅读了其中几个答案后,我在 2018 年 8 月结合使用了几个答案,通过 lambda for python 3.6 检索查询字符串参数。

首先,我去了 API Gateway -> 我的 API -> 资源(在左侧) -> 集成请求。在底部,选择映射模板,然后输入内容类型application/json

接下来,选择 Amazon 提供的 Method Request Passthrough 模板,然后选择 save and deploy your API。

然后,lambdaevent['params']是您访问所有参数的方式。对于查询字符串:event['params']['querystring']

于 2018-08-14T17:55:28.550 回答