Reputation: 15579
I've created a lambda function and API gateway endpoint so that it echoes the query and header parameters it receives, and I want to parse the whole payload to JSON for manageability.
The received payloads is in this form:
"{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}"
It is not trivial to parse this manually (there is no escaping in the strings). What format is this, and are there some node libs to parse this format to JSON?
My requestTemplate:
"requestTemplates": {
"application/json": "{\"httpMethod\": \"$context.httpMethod\", \"route\": \"$input.params('route')\", \"query\": \"$input.params().querystring\", \"header\": \"$input.params().header\"}"
},
Upvotes: 3
Views: 2202
Reputation: 9020
You may find it easier to use the [Method Request passthrough] template (available via the Generate template drop down in the console), which will turn the values into a dictionary:
## 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"
}
}
Upvotes: 2
Reputation: 200446
If you use this mapping template in API Gateway it will be parsed for you, and available in the Lambda function as event.headers.Accept-Encoding
, event.headers.Accept-Language
etc.
{
"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"
}
Note that I got this from kennbrodhagen's excellent answer to this question: How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway and I just added the "stage" property to make the API Gateway Stage available in the Lambda function.
Upvotes: 2