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

时间:2015-07-09 23:20:12

标签: amazon-web-services aws-lambda aws-api-gateway

例如,如果我们想要使用

GET /user?name=bob

GET /user/bob

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

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

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

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

21 个答案:

答案 0 :(得分:205)

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

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

enter image description here

然后,您就可以访问查询参数,路径参数和标题,如此

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

答案 1 :(得分:199)

实现这一目标的步骤是:

在API网关控制台中......

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

  5. 点击模板下拉框旁边的复选框(我假设这是最终保存的内容)

答案 2 :(得分:123)

我使用此映射模板为Lambda事件提供Body,Headers,Method,Path和URL Query String Parameters。我写了一篇博文,更详细地解释了模板: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
  }  
}

答案 3 :(得分:36)

目前AWS上的API网关控制台中包含一个下拉模板。

对于您的API,请单击资源名称...然后获取

展开“正文映射模板”

输入

  

应用/ JSON

for Content-Type(必须明确输入)并单击勾选

将打开一个新窗口,其中包含“生成模板”和下拉列表(参见图片)。

选择

  

方法请求直通

enter image description here

然后点击保存

要访问任何变量,只需使用以下语法(这是Python) 例如网址:

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'])

因此无需明确命名或映射您想要的每个变量。

答案 4 :(得分:24)

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

答案 5 :(得分:22)

为了将参数传递给lambda函数,您需要在API网关请求和lambda函数之间创建映射。映射在Integration Request - >中完成。所选API网关资源的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('$')
}

注意:单击复选符号以保存模板。您可以使用" test"来测试您的更改。资源中的按钮。但是,为了在AWS控制台中测试查询字符串参数,您需要在资源的Method Request部分中定义参数名称。

注意:查看Velocity User Guide以获取有关Velocity模板语言的更多信息。

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

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo

答案 6 :(得分:15)

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

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

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

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

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

答案 7 :(得分:11)

现在,您应该能够使用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

答案 8 :(得分:5)

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

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

我认为最佳答案会在构建真实内容时产生更有用的东西,但是为了使用AWS中的模板快速运行hello,这非常有用。

答案 9 :(得分:4)

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

复制

答案 10 :(得分:4)

GET / user?name = bob

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

GET / user / bob

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

答案 11 :(得分:2)

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

对于GET / user?name = bob

 var name = event.params.querystring.name;

但这并不能解决GET用户/ bob问题。

答案 12 :(得分:1)

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

  1. 打开API网关资源的映射模板,并添加新的application/json内容类型:

API Gateway mapping template

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

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

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

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

答案 13 :(得分:1)

Python 3.8 with 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}]

答案 14 :(得分: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 event ['headers'] ['parametername']等等

答案 15 :(得分:0)

作为@Jonathan的回答,在集成请求中标记使用Lambda代理集成后,您应在源代码中实现以下格式,并通过 502错误网关错误。

NodeJS 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网关上部署资源。 响应JSON仅返回 body 中设置的正确值。 因此,您可以从事件获取路径,参数,标题,正文值

  

const {路径,queryStringParameters,标头,正文} =事件;

答案 16 :(得分:0)

答案 17 :(得分:0)

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

答案 18 :(得分:0)

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

 protodb?sql=select * from protodb.prototab
通过API网关的URL

到Node.js 12 Lambda函数。我尝试了其他答案中的许多想法,但我真的想以最可能的API网关UI本机方式做点什么,因此我想出了一个对我有用的方法(截至2020年12月,适用于API Gateway的UI) :

在给定API的API网关控制台上,在资源下,选择get方法。然后选择其集成请求,并在页面顶部为lambda函数填写数据。

滚动到底部,然后打开“映射模板”部分。如果未定义模板,则选择“请求正文传递”。(推荐)。

点击添加映射模板,然后创建一个内容类型为application / json的模板,然后点击复选标记按钮。

对于该映射模板,请在下拉列表中选择“方法请求”传递以生成模板,该模板将使用AWS传递所有内容的通用方式填充其下方的文本框。

点击保存按钮。

现在,当我对其进行测试时,我无法获得参数作为Lambda函数中节点JS下的event.sql通过。事实证明,当API网关将URL sql查询参数发送给Lambda函数时,Node.js会通过以下方式获取它:

 var insql = event.params.querystring.sql;

所以花了我一些时间的窍门是使用JSON.stringify显示完整的事件堆栈,然后逐步浏览各个部分,以便能够从查询字符串中提取sql参数。

因此,基本上,您可以在API网关中使用默认的直通功能,其技巧是在使用Lambda函数时如何传递参数。

答案 19 :(得分:0)

对我有用的方法是

  1. 转到集成请求
  2. 点击 URL 查询字符串参数
  3. 点击添加查询字符串
  4. 在名称字段中输入查询名称,这里是“名称”
  5. 在映射自字段中,输入“method.request.querystring.name”

答案 20 :(得分:-1)

在阅读了这些答案中的几个之后,我在2018年8月使用了多个答案的组合通过python 3.6的lambda检索了查询字符串参数。

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

接下来,选择Amazon提供的方法请求传递模板,然后选择保存并部署您的API。

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