Search code examples
amazon-web-servicesaws-lambda

How do I add "event JSON" to a AWS Lambda GET request?


I've got a Lambda set up through API Gateway. The Lambda takes a value SeriesId from the event JSON and uses it. Here's the Lambda code:

import json
import boto3
from boto3.dynamodb.conditions import Key

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('TV-App-Seasons')

def lambda_handler(event, context):
    seriesId = int(event["SeriesId"])
    response = table.query(KeyConditionExpression=Key("SeriesId").eq(seriesId))
    data = response['Items']
            
    return {
        'statusCode': 200,
        'body': data
    }

My test event works with the following event JSON:

{
  "SeriesId": 0
}

However, how do I add this to my request from React? Since it's a GET request I can't add a body. I tried pathparameters in Postman, which works perfectly fine; URL/Seasons?SeriesId=0. However, when I try this in React I get a KeyError! React code:

 function getSeasons(seriesId: number) {
    const response = fetch("URL/stage/Seasons?SeriesId=" + seriesId, {
      method: "GET",
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      }
    })
      .then([...]);
  }

KeyError:

  {
    errorMessage: "'SeriesId'", 
    errorType: 'KeyError', 
    requestId: '1a71a2d3-8c37-475d-8672-2958e3c84ca1',
    stackTrace: Array(1)
  }

I've triple checked the URL, so it has to be something else. Based on this SO post I tried swapping seriesId = int(event["SeriesId"]) with seriesId = int(event["pathparameters"]["SeriesId"]), but to no avail. Still a KeyError (and now my test fails as well!)

I'm really baffled that this works through Postman / in browser but not through React. I've got another Lambda which doesn't use a event JSON which I can access with both Postman and React, so I don't think it's my React code. Also, CORS is enabled. Does anyone see something amiss / knows how to solve this problem? Thanks in advance!

EDIT: Based on Quassnoi's help and this article I've updated my Lambda / API Gateway settings to act as a proxy. Now I can read the SeriesId from the queryStringParameters. After some configuration where this SO post helped a lot, it now seems to work! I just need to refactor my React code a bit to deal with the preflight CORS response (at least, that's what I think)


Solution

  • However, how do I add this to my request from React? Since it's a GET request I can't add a body.

    You have two options:

    1. Set up a Proxy Integration with Gateway. A proxy integration will convert your GET request to a Gateway event, which will have everything the HTTP request had: the URL, complete with the parameters, the HTTP method, the headers, etc.

    2. Set up a Custom Integration with a mapping template. The template (a piece of code in Apache VTL) will transform a parameter or a fragment of path from your GET request to a simple JSON, which will be passed to your Lambda.

    It looks like you've set up either a proxy integration or a custom integration without a mapping template.

    In both these cases, the variable event will not have the key SeriesId.

    With the proxy integration, it will have the key queryStringParameters, which will contain a dictionary with all your query parameters.

    With a custom integration without a template, it will have some flavor of an empty value (None, or an empty string, or maybe an empty dictionary, I don't remember which).