首页 文章

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

提问于
浏览
236

例如,如果我们想要使用

GET /user?name=bob

要么

GET /user/bob

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

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

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

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

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

17 回答

  • 15

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

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

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

  • 18

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

    对于GET / user?name = bob

    var name = event.params.querystring.name;
    

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

  • 187

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

    • 打开API网关资源的映射模板并添加新的 application/json content-tyap:

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

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

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

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
    • 你're done. From this point, your Lambda function'的逻辑可以使用查询字符串参数 .
      祝好运!
  • 4

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

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

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

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

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

  • 4

    作为@ Jonathan的回答,在 Integration Request 中标记 Use Lambda Proxy integration 之后,在源代码中,您应该通过 502 Bad Gateway 错误实现以下格式 .

    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网关上部署 resource . 响应JSON只返回 body 中的哪个设置是正确的 . 因此,您可以从事件中获取路径,参数, Headers ,正文值

    const {path,queryStringParameters,headers,body} = event;

  • 147

    为了将参数传递给lambda函数,您需要在API Gateway请求和lambda函数之间创建映射 . 映射在所选API网关资源的 Integration Request - > 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模板语言的更多信息,请查看Velocity User Guide .

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

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

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

  • 0

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

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

    然后,您就可以访问查询参数,路径参数和 Headers

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

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

    GET / user?name = bob

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

    GET / user / bob

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

    实现这一目标的步骤是:

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

    • 转到 Resources -> Integration Request

    • 点击模板下拉列表旁边的加号或编辑图标(奇怪我知道,因为模板字段已经打开,此处的按钮看起来是灰色的)

    • 在内容类型字段中显式键入 application/json ,即使它显示默认值(如果不这样做,它将不会保存,也不会给出错误消息)

    • 把它放在输入映射 { "name": "$input.params('name')" }

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

  • 2

    如果您使用JAVA作为Lambda函数,可以使用Lambada Framework来处理这些内容 .

  • 0

    在阅读了几个这样的答案之后,我在2018年8月使用了几个组合来检索查询字符串params到lambda for python 3.6 .

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

    接下来,选择Amazon提供的Method Request Passthrough模板,然后选择保存并部署您的API .

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

  • 0

    以下参数映射示例通过JSON有效负载将所有参数(包括路径,查询字符串和标头)传递到集成 endpoints

    #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

  • -1

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

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

    展开“正文映射模板”

    输入

    application / json

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

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

    选择

    方法请求直通

    然后单击“保存”

    要访问任何变量,只需使用以下语法(这是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'])
    

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

  • 32

    接受的答案对我来说很好,但扩展了gimenete的答案,我想要一个通用模板,我可以使用它来传递所有查询/路径/ Headers 参数(就像现在的字符串一样),我提出了以下模板 . 我在这里发布它,以防有人发现它有用:

    #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
    }
    
  • 1

    你可以使用Lambda作为"Lambda Proxy Integration",参考这个[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']等等

相关问题