How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway

350,979

Solution 1

As of September 2017, you no longer have to configure mappings to access the request body.

All you need to do is check, "Use Lambda Proxy integration", under Integration Request, under the resource.

enter image description here

You'll then be able to access query parameters, path parameters and headers like so

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']

Solution 2

The steps to get this working are:

Within the API Gateway Console ...

  1. go to Resources -> Integration Request
  2. click on the plus or edit icon next to templates dropdown (odd I know since the template field is already open and the button here looks greyed out)
  3. Explicitly type application/json in the content-type field even though it shows a default (if you don't do this it will not save and will not give you an error message)
  4. put this in the input mapping { "name": "$input.params('name')" }

  5. click on the check box next to the templates dropdown (I'm assuming this is what finally saves it)

Solution 3

I have used this mapping template to provide Body, Headers, Method, Path, and URL Query String Parameters to the Lambda event. I wrote a blog post explaining the template in more detail: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/

Here is the Mapping Template you can use:

{
  "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
  }  
}

Solution 4

These days a drop-down template is included in the API Gateway Console on AWS.

For your API, click on the resource name... then GET

Expand "Body Mapping Templates"

Type in

application/json

for Content-Type (must be explicitly typed out) and click the tick

A new window will open with the words "Generate template" and a dropdown (see image).

Select

Method Request passthrough

enter image description here

Then click save

To access any variables, just use the following syntax (this is Python) e.g. URL:

https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5

You can get variables as follows:

from __future__ import print_function

import boto3
import json

print('Loading function')


def lambda_handler(event, context):
    print(event['params']['querystring']['token'])
    print(event['params']['querystring']['uid'])

So there is no need to explicitly name or map each variable you desire.

Solution 5

In order to pass parameters to your lambda function you need to create a mapping between the API Gateway request and your lambda function. The mapping is done in the Integration Request -> Mapping templates section of the selected API Gateway resource.

Create a mapping of type application/json, then on the right you will edit (click the pencil) the template.

A mapping template is actually a Velocity template where you can use ifs, loops and of course print variables on it. The template has these variables injected where you can access querystring parameters, request headers, etc. individually. With the following code you can re-create the whole querystring:

{
    "querystring" : "#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0)&#end$util.urlEncode($key)=$util.urlEncode($input.params().querystring.get($key))#end",
    "body" : $input.json('$')
}

Note: click on the check symbol to save the template. You can test your changes with the "test" button in your resource. But in order to test querystring parameters in the AWS console you will need to define the parameter names in the Method Request section of your resource.

Note: check the Velocity User Guide for more information about the Velocity templating language.

Then in your lambda template you can do the following to get the querystring parsed:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
Share:
350,979
MonkeyBonkey
Author by

MonkeyBonkey

CTO of Pictorious.com, a mobile app for turning photo sharing into a fun meme-game.

Updated on December 27, 2021

Comments

  • MonkeyBonkey
    MonkeyBonkey over 2 years

    for instance if we want to use

    GET /user?name=bob

    or

    GET /user/bob

    How would you pass both of these examples as a parameter to the Lambda function?

    I saw something about setting a "mapped from" in the documentation, but I can't find that setting in the API Gateway console.

    • method.request.path.parameter-name for a path parameter named parameter-name as defined in the Method Request page.
    • method.request.querystring.parameter-name for a query string parameter named parameter-name as defined in the Method Request page.

    I don't see either of these options even though I defined a query string.

  • Lucas
    Lucas almost 9 years
    Did you ever get this to send through URL parameters in URLs like /user/bob where the route was /user/{username}? I have tried all kinds of permutations, but have been unable to work that out.
  • Vikas Jangra
    Vikas Jangra about 8 years
    Amazing! I was struggling with passing things along generically to my handler. Best answer here.
  • Parthapratim Neog
    Parthapratim Neog about 8 years
    I did this, but I am not getting anything yet. Its showing Undefined. How are we supposed to sent the Parameters in the URL? and do we need specify the variable name in the url like in a normal GET url scenario? Please help me out with this.
  • Parthapratim Neog
    Parthapratim Neog about 8 years
    Nevermind I got the result. The problem was, I added the mapping and just saved it, and did not deploy the api once again. Once I deployed the api with the new mapping, it worked just fine. Thanks a ton.
  • loretoparisi
    loretoparisi almost 8 years
    This is the best solution. Please remember to do Actions>Deploy API then (I wasted my time forgetting this...). The associated lambda arn will take the change immediately after the deployment. You can check it in Stages > #stage (like: prod) > Deployment History.
  • matsev
    matsev over 7 years
    @shashu10 See my answer
  • Gustavo Straube
    Gustavo Straube over 7 years
    I'm not sure why, but the proxy integration usually doesn't work for me. I had to remove it from the latest APIs I've created.
  • Stephen Tetreault
    Stephen Tetreault over 7 years
    same ^ furthermore I've had CORS issues with API Gateway. Following along with AWS docs I was not able to get CORS working. However I found an old Medium article from mid-late 2015 which had a manual way of setting up CORS and that worked.
  • Tom Saleeba
    Tom Saleeba almost 7 years
    This still works as of May 2017 but it returns the JS object that API Gateway creates for you rather than the actual query string. This is annoying for me because I'm trying to parse the query string to turn repeated params into an array.
  • AaronBaker
    AaronBaker over 6 years
    This is a great tip. But, keep in mind that turning on Lambda Proxy Integration could cause a "Malformed Lambda Proxy Response" error. Here's how to fix it: stackoverflow.com/questions/43708017/…
  • user3685427
    user3685427 over 6 years
    I can't begin to tell you how useful your blog is. I found the "eturn-html-from-aws-api-gateway" post first and followed it, because it's exactly what I needed. Now I need to pass some parameters in to the function and modify the html based on that - and again you're the only one with a real guide! All the other guides I've found seem to miss the point.
  • Neo
    Neo over 5 years
    its event.queryStringParameters.name
  • Matt Fletcher
    Matt Fletcher over 5 years
    Fab, I wanted to be able to use the same function for both POST (with JSON body) requests and GET with query strings. Works a dream. Thanks!
  • nxmohamad
    nxmohamad almost 5 years
    @benv is this the full template?
  • Anders Kitson
    Anders Kitson almost 4 years
    I had to do event.queryStringParameters.name
  • Stefan Sprenger
    Stefan Sprenger about 2 years
    Both undefined for me
  • chaulap
    chaulap about 2 years
    Which is undefined the pathParameters object or in this case the name? Or is it the queryStringParameters ?