Reputation: 357
I know there are a lot of questions about mapping the request data, but neither one helped me.
So, what i am trying to achieve is an API endpoint mapped to a lambda. The request to that endpoint is forwarded when a bucket triggers a 404, and the parameters are passed to the lambda via the request path, like: /{image_name}/{width}/{height}.
My lambda's code simply calls context.succeed(event, context);
In the Method request configuration the request path's parameters were automatically created, .
In the integration request I have created three mapping templates: plain/text, plain/html, application/json with the same definition as bellow:
#set($inputRoot = $input.path('$'))
{
"name": $input.params('name'),
"width" : $input.params('width'),
"height" : $input.params('height'),
"params": $input.params(),
"resourcePath": $context.resourcePath,
}
When calling form an chrome rest client i get:
When calling the test from the console, i get the following response:
{"Type":"User","message":"Could not parse request body into json."}
The same response i get when I call curl or when I simply open the URL in the browser.
But in the logs from the console's test call I see:
Execution log for request test-request
Tue Sep 08 09:10:20 UTC 2015 : Starting execution for request: test-invoke-request
Tue Sep 08 09:10:20 UTC 2015 : API Key: test-invoke-api-key
Tue Sep 08 09:10:20 UTC 2015 : Method request path: {name=name, width=100, height=100}
Tue Sep 08 09:10:20 UTC 2015 : Method request query string: {}
Tue Sep 08 09:10:20 UTC 2015 : Method request headers: {}
Tue Sep 08 09:10:20 UTC 2015 : Method request body before transformations: null
Tue Sep 08 09:10:20 UTC 2015 : Endpoint request URI: <endpoint>:function:Magic/invocations
Tue Sep 08 09:10:20 UTC 2015 : Endpoint request headers: {
Authorization=<authorization>
Credential=<credential>,
SignedHeaders=accept;content-type;host;user-agent;x-amz-content-sha256;x-amz-date;x-amz-source-arn,
Signature=<signature>,
X-Amz-Date=20150908T091020Z,
X-Amz-Source-Arn=<ARN>/null/GET/image/{name}/{width}/{height},
Accept=application/json,
User-Agent=AmazonAPIGateway_ebkkwbbpo0,
Host=lambda.us-east-1.amazonaws.com,
X-Amz-Content-Sha256=<key>,
Content-Type=application/json
}
Tue Sep 08 09:10:20 UTC 2015 : Endpoint request body after transformations: {
"name": name,
"width" : 100,
"height" : 100,
"params": {path={name=name, width=100, height=100}, querystring={}, header={}},
"resourcePath": /image/{name}/{width}/{height},
}
Tue Sep 08 09:10:20 UTC 2015 : Endpoint response body before transformations: {"Type":"User","message":"Could not parse request body into json."}
Tue Sep 08 09:10:20 UTC 2015 : Endpoint response headers: {
x-amzn-ErrorType=InvalidRequestContentException:http://internal.amazon.com/coral/com.amazonaws.awsgirapi/,
x-amzn-RequestId=<RequestId>,
Connection=keep-alive,
Content-Length=68,
Date=Tue, 08 Sep 2015 09:10:20 GMT,
Content-Type=application/json}
Tue Sep 08 09:10:20 UTC 2015 : Method response body after transformations: {"Type":"User","message":"Could not parse request body into json."}
Tue Sep 08 09:10:20 UTC 2015 : Method response headers: {Content-Type=application/json}
Tue Sep 08 09:10:20 UTC 2015 : Successfully completed execution
As I see at some point, the URL path is parsed correctly, but I do not know what goes wrong. Also, I don't know why there is in the X-Amz-Source-Arn a null value in the path.
Thank you.
Upvotes: 1
Views: 3174
Reputation: 9
In case of lambda integration with path parameters, the path parameters should be mapped in the Integration request as follows.
Go to Integration Response -> Mapping Templates and add the following mapping of the path parameter to input values:
{ "itemId": "$input.params('catalogitemid')"}
Upvotes: 1
Reputation: 357
The problem is the integration request mapping template. You should double quote the fields that are string type, so they can later be converted to JSON. So in this example you should write:
#set($inputRoot = $input.path('$'))
{
"name": "$input.params('name')",
"width" : $input.params('width'),
"height" : $input.params('height'),
"params": "$input.params()",
"resourcePath": "$context.resourcePath",
}
It seemed odd to me, but this is the solution.
Also you don't need to write three mapping templates for this case, you should leave only the application/json
Upvotes: 10