Can you define a URL Query String Parameter for a get request?

New to serverless so sorry if this is obvious or there is a better way to do it. But where in the serverless.yml file can you define a URL Query String Parameter for a mapping template? Thanks!

You can use the custom request template to map your API Gateway query strings to the event object in your lambda function.

That part of the document has some typo currently, and I’ve opened a PR, meanwhile you can view my forked version of it here.

So for example, if you have a get request like this:

https://example.com/dev/whatever?foo=bar%some_data=12345

In your serverless.yml:

functions:
  create:
    handler: posts.create
    events:
      - http:
          method: get
          path: whatever
          request:
            template:
              application/json: '{ "foo" : "$input.params(''foo'')", "someData": "$input.params(''some_data'')" }'

or if you like the multi-line version using > syntax:

functions:
  create:
    handler: posts.create
    events:
      - http:
          method: get
          path: whatever
          request:
            template:
              application/json: >
                {
                  "foo" : "$input.params('foo')",
                  "someData": "$input.params('some_data')"
                }

notice single-quotes must be doubled in single-quoted strings, but in the multi-line version, there is no more single-quotes, so no need to double it.

and now you can access them through the event object in the lambda function:

module.exports.handler = function(event, context, callback) {
  // event is now: {
  //   foo: 'bar',
  //   someData: '12345'
  // }
};
2 Likes

This doesn’t work for me. I’m trying to define a simple GET HTTP event that takes a single query string parameter ‘foo’.

In my serverless.yml

functions:
  hello:
    handler: handler.hello
    events:
      - http: GET hello
    request:
      template:
      application/json: '{ "foo" : "$input.params(''foo'')" }'

My lambda function simply returns the event object. The event mapping remains the same (default). The query string parameter key/valueDo you see anything wrong with the above? Do you know of any examples demonstrating how to define an HTTP event containing URL parameters? e.g. users/{userid}

Thanks!

Your indentation for template is incorrect, the application/json should
be one more indented than the template.

request:
  template:
    application/json: '{ "foo" : "$input.params(''foo'')" }'

One more thing about debugging these things, note that you’re just using the serverless framework to control things in AWS, which you’ll normally have to setup by yourself.

In other words, you can view all the things serverless has done for you in the AWS console!

For example let see what the template thing is doing to the API Gateway:

  1. Login to AWS console and go to API Gateway.
  2. On the left sidebar select the API you want to view under the APIs section (which should be the “stage DASH service” in you serverless.yml).
  3. You’ll see the API path and method on the right, select the method you want to view. In your case, it’s the GET under /hello
  4. Now there are 4 boxes, for the request template click on the top right Integration Request (and response template is the bottom right Integration Response)
  5. Scroll down and click on the Body Mapping Templates, you should see all the templates you defined for the response template (plus some more default ones such as application/x-www-form-urlencoded). In your case you should see a application/json. Select the template to view the template, for application/json, the content should be a valid JSON string.

Dax,

Thank you for the through explanation. I do understand that serverless is attempting to automate the APIG configuration that I would otherwise do manually. I’m viewing the APIG in the AWS console after each deployment.

I fixed the indentation, as you suggested, but (re)deploying the function still does not change the request body mapping template in the API Gateway. The function definition now looks like:

functions:
  hello:
    handler: handler.hello
    events:
      - http: GET hello
    request:
      template:
        application/json: '{ "foo" : "$input.params(''foo'')" }'

Under /hello > GET > Integration Request > Body Mapping Templates I see that the default templates are still in use.

  • application/json
  • application/x-www-form-urlencoded

It seems that my request template is ignored. Could this be a bug? I will try to create a new function/HTTP event using the same request template in the serverless.yml and see if updating an existing mapping template is the issue.

I’m using the latest serverless (v1.0.0-rc.2).

Thank you for your replies.

-Nick

Thanks for this answer helped me

Hi,

I am using the approach described above and I am sure my indentation and syntax is correct, but when I run the sls deploy script it gives me the following error:

Warning! You’re using the LAMBDA-PROXY in combination with request / response configuration in your function “chargePointRead”. This configuration will be ignored during deployment.

When I check through the AWS UI it shows that no request params have been set.

From Serverless 1.0 (which was released after those posts) the default is proxy-lambda integration. You need to add integration: lambda to your http event configuration to switch back to lambda integration. See https://serverless.com/framework/docs/providers/aws/events/apigateway#lambda-integration

1 Like

With proxy-lambda integration (default one with serverless framework), we can access directly to the source Ip through the event :

console.log( event.requestContext.identity.sourceIp )