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

Mon*_*key 310 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在"方法请求"页面中定义的名称的查询字符串参数.

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

Jon*_*han 248

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

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

在此输入图像描述

然后,您就可以像这样访问查询参数,路径参数和标题

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的提示.但是,请记住,启用Lambda代理集成可能会导致"格式错误的Lambda代理响应"错误.以下是解决方法:/sf/ask/3059561221/ (19认同)
  • 有没有办法在java中执行此操作,同时保持实现`RequestHandler`提供的透明反序列化? (4认同)
  • 如果 lambda 函数是使用 C#.NET Core 编写的,那么`event` 对象是什么? (3认同)
  • 这个设置在哪里? (2认同)
  • @MattWestlake您可以在API Gateway中创建一个名为user的资源,并在其下创建一个名为{name}的资源。 (2认同)
  • 我只想提及,在进行此更改之后,我还必须转到Amazon API Gateway-> Actions-> Deploy API并重新部署到实时环境。 (2认同)

Mon*_*key 204

实现这一目标的步骤是:

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

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

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

  • 您是否曾通过/ user/bob等网址中的URL参数发送此路由,其中​​路由为/ user/{username}?我尝试了各种各样的排列,但一直无法解决这个问题. (9认同)
  • 卢卡斯,我使用/ user/{username}模式让它工作.请记住,如果您的GET资源路径是/ user/{username},则在步骤4中输入映射看起来像这样{"name":"$ input.params('username')"} (6认同)
  • 有没有人知道是否有任何官方文件?最好只传递所有查询参数或处理比空字符串更优雅的可选值 (5认同)
  • iOS开发人员的一个提示:在将每个变量定义为查询字符串(在"方法请求"下)和部署API之前,API网关不会传递查询数据.在部署之前,它可以从控制台测试开始,但会从应用程序的查询中删除. (5认同)
  • @axel在此处记录:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html (3认同)
  • 什么是"整合请求"?没有这样的项目 (2认同)

ken*_*gen 128

我使用此映射模板为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-网关/

这是您可以使用的映射模板:

{
  "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
  }  
}
Run Code Online (Sandbox Code Playgroud)

  • 没关系,我得到了结果.问题是,我添加了映射并保存了它,并且没有再次"部署"api.一旦我使用新映射部署api,它就可以正常工作了.万分感谢. (8认同)
  • 这应该在lambda/gateway文档中 (7认同)

Dir*_*see 39

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

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

展开"正文映射模板"

输入

应用程序/ JSON

对于Content-Type(必须明确键入)并单击勾选

将打开一个新窗口,其中包含"生成模板"和下拉列表(请参见图像).

选择

方法请求passthrough

在此输入图像描述

然后单击"保存"

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

https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5
Run Code Online (Sandbox Code Playgroud)

您可以获得如下变量:

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'])
Run Code Online (Sandbox Code Playgroud)

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


Ben*_*enV 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
}
Run Code Online (Sandbox Code Playgroud)


gim*_*ete 23

为了将参数传递给lambda函数,您需要在API网关请求和lambda函数之间创建映射.映射在所选API网关资源的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('$')
}
Run Code Online (Sandbox Code Playgroud)

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

注意:有关Velocity模板语言的更多信息,请查看Velocity用户指南.

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

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的解决方案.请记得做"动作>部署A​​PI"然后(我浪费时间忘记了这个......).关联的lambda arn将在部署后立即进行更改.您可以在`Stages> #stage(如:prod)>部署历史记录`中查看它. (8认同)

use*_*526 15

由于试图回答我自己的问题,一部分在这里,我遇到了这一招.

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

{
    "querystring": "$input.params().querystring"
}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 15

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

对于 GET /user?name=bob

 var name = event.queryStringParameters.name;
Run Code Online (Sandbox Code Playgroud)

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

  • 它的 event.queryStringParameters.name (3认同)

Jac*_*AWS 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-代理资源

  • 我不知道为什么,但代理集成通常对我不起作用。我不得不从我创建的最新 API 中删除它。 (2认同)

Dmi*_*nko 6

GET / user?name = bob

{
    "name": "$input.params().querystring.get('name')"
}
Run Code Online (Sandbox Code Playgroud)

GET /用户/鲍勃

{
    "name": "$input.params('name')"
}
Run Code Online (Sandbox Code Playgroud)


cha*_*lap 6

为了获取查询参数,您queryStringParameters可以像这样将它们放入对象中

const name = event.queryStringParameters.name;
Run Code Online (Sandbox Code Playgroud)

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

const name = event.pathParameters.name;
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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

我认为,最基本的答案在构建真实的东西时会产生更多有用的东西,但是对于使用来自AWS的模板快速运行hello的世界来说,这样做非常有用。


mat*_*sev 5

以下参数映射示例通过 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
  }
}
Run Code Online (Sandbox Code Playgroud)

实际上,此映射模板输出负载中的所有请求参数,如下所述:

{
  "parameters" : {
     "path" : {    
       "path_name" : "path_value", 
       ...
     }
     "header" : {  
       "header_name" : "header_value",
       ...
     }
     'querystring" : {
       "querystring_name" : "querystring_value",
       ...
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

复制自Amazon API Gateway 开发人员指南