首页 > 解决方案 > 如何将查询字符串和标头映射到 AWS C# lambda 函数参数

问题描述

我有带有 2 个查询字符串参数的 AWS Gateway REST API

https://xxxxxx.xxxx.us-east-1.amazonaws.com/dev/pets?type=dog&page=1

API 的调用者也包含x-api-key在标头中。我希望 API 网关将查询字符串参数传递x-api-key给 lambda 函数。所以在AWS API Gateway Console我配置Integration Request如下

在此处输入图像描述

lambda 函数看起来像这样

namespace AWSLambda1
{
    public class Function
    {
        public string FunctionHandler(LambdaRequest request, ILambdaContext context)
        {
            return string.Format("{0},{1},{2}", request.Type, request.Page, request.ApiKey);
        }        
    }
}

public class LambdaRequest
{
    public string Type { get; set; }
    public string Page { get; set; }
    public string ApiKey { get; set; }
}

问题
1> 当 lambda 函数接收到请求时,TypeandPage属性为 NULL。

2>根据文档 API Gateway 可以使用命名约定映射 http 标头method.request.header.{param_name},但是当我尝试设置映射时,method.request.header.x-api-key它会抛出错误

指定的映射表达式无效:验证结果:警告:[],错误:[指定的映射表达式参数无效:method.request.header.x-api-key]

我不确定如何将这些查询字符串和标头映射到 C# lambda 对象

(请注意,我已经阅读了建议将 JObject 作为 lambda 函数的参数的SO 帖子。但它仅在我启用Use Lambda Proxy integrationin时才对我有效Integration Request。在这种情况下,API 网关将所有信息传递给 lambda。这可能对我有用,但我试图避免将不需要的信息传递给 lambda 函数)

标签: amazon-web-servicesaws-lambdaaws-api-gateway

解决方案


在此处添加完整答案。

标题问题

首先,您需要确保已添加标题条目Method Request,然后您可以Integration Request使用 mapping 将其映射method.request.header.x-api-key。发生错误是因为您没有添加Method Request部分,而是Integration Request仅尝试对其进行配置。

在此处输入图像描述 在此处输入图像描述

Lambda 有效负载问题

看起来你没有使用Lambda Proxy Integration. 如果您使用 Lambda 代理集成,那么您将获得完整的事件 JSON 对象事件数据到 Lambda。类似于您分享的帖子中给出的答案。这个 JSON 对象将包含标头、查询参数、路径变量、url、请求正文等。如果您想查看一些关于其外观的示例,只需在 Lambda 上创建 API Gateway 测试事件。

现在,如果您不想使用 Lambda 代理集成但想限制发送到 Lambda 的内容,那么您将必须创建集成映射模板以仅向 Lambda 发送所需的信息,例如标头、有效负载、查询参数等,来自API 网关。

示例集成模板。

{
  "body" : $input.json('$'),
  "headers": {
    #foreach($header in $input.params().header.keySet())
    "$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end

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

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

    #end
  }  
}

参考 -

https://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html


推荐阅读