Query parameters are not configured in the API Gateway
I have this in the settings.yml for an application that should only demonstrate how to read parameters from a GET query string or a POST body:
greetingsapi:
description: Greetings
resources:
/hello/{name}:
methods: GET
integration:
lambda: greetings.index
code.js is
exports.handler = function(event, context) {
var data = "Hello " + event.name + "!\n";
data += "Event\n" + JSON.stringify(event, null, 2) + "\n";
data += "Context\n" + JSON.stringify(context, null, 2) + "\n";
context.succeed(data);
};
echo '{"name": "Paolo"}' | gordon run greetings.index works as expected. However it seems that the events object is always empty when I call through the API gateway:
curl 'https://...eu-west-1.amazonaws.com/dev/hello/Paolo'
"Hello undefined!\nEvent\n{}\n etc"
Actually looking into the AWS API Gateway there are no parameters defined for that method:

I'm probably missing some bits of configuration. I looked into the examples and the documentation, checked several alternatives (also POST instead of GET) but the parameter never gets to the function.
Have you check in the "Request Paths" section? That {name} is not a Query string but a request path.
This is how the dashboard looks like for the apigateway example (https://github.com/jorgebastida/gordon/tree/master/examples/apigateway)

You're right (obviously), the name parameter is in the Request Paths.
I read http://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html and realized that I was missing the configuration for the Integration Request.
I added this manually:

The test in the API Gateway page passed. I deployed the API and it works with curl as well.
I have to figure out with piece of configuration I'm missing in gordon. I expected I had nothing to do and that declaring the parameter would setup the Integration Request too.
I made further investigations.
I cloned the gordon repository, moved to the examples/apigateway folder, changed the name of the bucket and deployed the example.
That also doesn't configure the Integration Request.
You can try curl https://dpyif1qb1g.execute-api.eu-west-1.amazonaws.com/dev/shop/x which is defined as /shop/{item} in settings.yml
I modified the example to print out the events object, which is empty.
Which is the way to access the value of item? In my previous comment I show how to do it using Integration Request.
I added an explicit parameters definition:
/shop/{item}:
methods: GET
integration:
lambda: helloworld.hellojs
parameters:
integration.request.querystring.item: method.request.path.item
(I switched to helloworld.hellojs because I'm more familiar with JS).
The AWS documentation hints that the item from the URL path should go to the right and the destination should go to the left. I'm not sure that querystring is the way to tell AWS to put that item into the events object.
With those lines gordon apply fails:
Applying project...
0001_p.json (cloudformation)
✓ No updates are to be performed.
0002_pr_r.json (custom)
✓ code/contrib_lambdas_version.zip (dcfc39a5)
✓ code/helloworld_hellojs.zip (25db66b4)
✓ code/helloworld_hellopy.zip (5cecbbbc)
0003_r.json (cloudformation)
UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS waiting... |
Unfortunately there is no detailed error message.
All the examples that define parameters for the API Gateway don't use those parameters in the lambda functions. Could you give a working example of a lambda function that uses those parameters? Thanks.
A final remark: in the spirit of convention over configuration (I remember your comment on HN) I think that we shouldn't even declare how to map parameters to events. gordon should automatically configure the API Gateway to pass any parameter to lambda. Path and querystring parameters should be the same. Parameters from the headers could get some special name, such has HEADER_parameter.
The last two lines here shouldn't be needed:
/parameters:
# http://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html
methods: GET
parameters:
method.request.header.color: True
integration:
lambda: helloworld.hellopy
responses:
- pattern: ""
code: "200"
parameters:
integration.request.querystring.color: method.request.header.color
I eventually realized that if I POST a JSON to an API Gateway URL it gets forwarded to the events object in Lambda. This is from https://github.com/jorgebastida/gordon/tree/master/examples/apigateway
$ curl -X POST -H "Content-Type: application/json" -d '{"this":"is","json":"data"}' \
https://your-api-gw-url.amazonaws.com/dev/complex/implementation
"Hello from js!\nEvent\n{\n \"this\": \"is\",\n \"json\": \"data\"\n}\n"
That is totally OK for sending data.
Just found this. @pmontrasio wondering if #117 is related to this?