【问题标题】:Parse AWS API Gateway header in Lambda在 Lambda 中解析 A​​WS API Gateway 标头
【发布时间】:2016-07-15 21:29:37
【问题描述】:

我创建了一个 lambda 函数和 API 网关端点,以便它回显它接收到的查询和标头参数,并且我想将整个有效负载解析为 JSON 以便于管理。

接收到的payload是这样的形式:

"{Accept=*/*, 
Accept-Encoding=gzip, 
deflate, 
Accept-Language=nb-NO,nb;q=0.8,no;q=0.6,nn;q=0.4,en-US;q=0.2,en;q=0.2,sv;q=0.2,da;q=0.2, 
Authorization=COzTjCKD6VHTC, 
Cache-Control=no-cache, 
User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36, 
Via=1.1 7822a0bcea47c939c09def064206add3.cloudfront.net (CloudFront), X-Amz-Cf-Id=Bd_gFYsmhx0jK0eKf-3sZwwRozXtFoYC5UEFDDLKWYJkq6AR_L0Cfw==, 
X-Forwarded-For=89.8.222.70, 205.251.218.72, 
X-Forwarded-Port=443, X-Forwarded-Proto=https}"

手动解析它并非易事(字符串中没有转义)。这是什么格式,是否有一些节点库可以将此格式解析为 JSON?

我的请求模板:

"requestTemplates": {
    "application/json": "{\"httpMethod\": \"$context.httpMethod\", \"route\": \"$input.params('route')\", \"query\": \"$input.params().querystring\", \"header\": \"$input.params().header\"}"
  },

【问题讨论】:

    标签: node.js amazon-web-services aws-lambda aws-api-gateway


    【解决方案1】:

    您可能会发现使用 [Method Request passthrough] 模板(可通过控制台中的 Generate template 下拉菜单获得)更容易,这会将值转换为字典:

    ##  See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
    #set($allParams = $input.params())
    {
    "body-json" : "$input.json('$')",
    "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
    },
    "stage-variables" : {
    #foreach($key in $stageVariables.keySet())
    "$key" : "$util.escapeJavaScript($stageVariables.get($key))"
        #if($foreach.hasNext),#end
    #end
    },
    "context" : {
        "account-id" : "$context.identity.accountId",
        "api-id" : "$context.apiId",
        "api-key" : "$context.identity.apiKey",
        "authorizer-principal-id" : "$context.authorizer.principalId",
        "caller" : "$context.identity.caller",
        "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
        "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
        "cognito-identity-id" : "$context.identity.cognitoIdentityId",
        "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
        "http-method" : "$context.httpMethod",
        "stage" : "$context.stage",
        "source-ip" : "$context.identity.sourceIp",
        "user" : "$context.identity.user",
        "user-agent" : "$context.identity.userAgent",
        "user-arn" : "$context.identity.userArn",
        "request-id" : "$context.requestId",
        "resource-id" : "$context.resourceId",
        "resource-path" : "$context.resourcePath"
        }
    }
    

    【讨论】:

    • 这是控制台的新功能吗?我喜欢它在“上下文”中传递所有信息的方式。
    • 非常感谢,看起来很棒!但是这个下拉菜单在哪里?
    • @MarkB 这是在最近的更新中添加到控制台的。修改模板时有两个下拉菜单。这个新模板在 Generate template 下拉菜单中以 [Method Request passthrough] 的形式提供。
    • @Bob Kinney 尝试使用此模板时发生错误,我发现这是因为“body-json”:“$input.json('$')”,不会没有引号会更好:“body-json”:$input.json('$')? (我的问题是引号内的json也使用双引号而不是单引号......)
    【解决方案2】:

    如果您在 API Gateway 中使用此映射模板,它将为您解析,并在 Lambda 函数中以 event.headers.Accept-Encodingevent.headers.Accept-Language 等形式提供。

    {
      "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
      },
      "stage" : "$context.stage"
    }
    

    请注意,我是从 kennbrodhagen 对这个问题的出色回答中得到的:How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway,我刚刚添加了“stage”属性以使 API Gateway Stage 在 Lambda 函数中可用。

    【讨论】:

      猜你喜欢
      • 2017-10-08
      • 2021-11-11
      • 2019-07-09
      • 2015-10-21
      • 1970-01-01
      • 2020-06-19
      • 2019-06-23
      • 2013-02-04
      • 1970-01-01
      相关资源
      最近更新 更多