Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query parameters are not configured in the API Gateway #8

Open
pmontrasio opened this issue Jun 2, 2016 · 5 comments
Open

Query parameters are not configured in the API Gateway #8

pmontrasio opened this issue Jun 2, 2016 · 5 comments

Comments

@pmontrasio
Copy link

pmontrasio commented Jun 2, 2016

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:

picture_2016-06-02_17 30 30 png

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.

@jorgebastida
Copy link
Owner

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)

captura de pantalla 2016-06-02 16 47 58

@pmontrasio
Copy link
Author

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:

picture_2016-06-03_16 32 08 png

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.

@pmontrasio
Copy link
Author

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

@pmontrasio
Copy link
Author

pmontrasio commented Jun 5, 2016

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.

@azizmb
Copy link

azizmb commented Dec 8, 2016

Just found this. @pmontrasio wondering if #117 is related to this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants