Access HTTP request (headers, query string, cookies, body) object in lambda with http endpoint

后端 未结 4 1401
忘掉有多难
忘掉有多难 2021-02-13 23:00

I am trying to see how to access the request header and body values from with in the lambda code. If the request body is in JSON format, it automatically seems to be parsed and

相关标签:
4条回答
  • 2021-02-13 23:41

    The request headers can be accessed using $input.params('header-name')

    Surprisingly, the User-Agent header cannot be accessed with above code. You need to jump through the following hoop to retrieve it:

    $context.identity.userAgent

    The request body/payload should be accessible using the following code. More reference here, here and here:

    {
       "reqbody": "$input.path('$')"
    }
    

    It is not yet clear if the request body is expected to be in JSON. It needs to be noted that the request is treated as UTF-8 according to this post.


    There currently seems to be two bugs:

    1. The "User-Agent" header is missing/being stripped off by the Amazon API.
    2. When the header values contain a double quote ("), the lambda function is not executed. (I do not see a log entry in the cloudwatch logs for such requests). Instead, the http response body contains the following:

      {
         "Type": "User",
         "message": "Could not parse request body into json."
      }
      

    An example request that fails in Amazon API

    I believe this would need to be corrected to be able to implement the ETag mechanism for caching.

    References:

    An Etag is expected to be enclosed within double quotes. The browser is expected to send this exact value back through the If-None-Match header, and this is where Amazon API breaks.

    Syntax for ETag?

    HTTP: max length of etag

    http://gsnedders.com/http-entity-tags-confusion

    0 讨论(0)
  • 2021-02-13 23:53

    You have to get the information you need in the template mapping and send them back your Lambda function, this is one of the template I used to send information to the Lambda function:

    {
       "params" : "$input.params()",
       "content-type-value" : "$input.params().header.get('Content-Type')",
       "body" : "$input.json('$')",
       "request-id": "$context.requestId",
       "method": "$context.httpMethod",
       "resource": "$context.resourcePath",
       "id": "$input.params('id')" //This is a path parameter in my case
    }
    

    You can do the same, or you can access params.path.id (again in my case). Here is the link to the documentation.

    Cheers,

    0 讨论(0)
  • 2021-02-13 23:57

    Seems like if no "Content-Type" is sent, AWS API Gateway defaults it to "application/json": https://forums.aws.amazon.com/thread.jspa?threadID=215471

    So just define the Mapping Template for "application/json".

    0 讨论(0)
  • 2021-02-14 00:00

    I updated the mapping template I used in the answer to one of the referenced questions to contain the userAgent property.

    {
      "method": "$context.httpMethod",
      "body": $input.json('$'),
      "userAgent": "$context.identity.userAgent",
      "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
      }  
    }
    

    A detailed explanation of the template is available here: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/

    0 讨论(0)
提交回复
热议问题