skip to Main Content

I want to use the AWS Lambda function below that is integrated with API Gateway to call 2 different routes. Please review the code below for that implementation:

import axios from 'axios';

export const handler = async (event) => {
  try {
    if (event.path === '/countries') {
      const countriesResponse = await axios.get('https://countriesnow.space/api/v0.1/countries/states');

      const countryNames = countriesResponse.data.data.map(country => country.name);

      return {
        statusCode: 200,
        body: JSON.stringify(countryNames),
      };
      
    } else if (event.path === '/states') {
      const { country } = JSON.parse(event.body);

      const statesResponse = await axios.post('https://countriesnow.space/api/v0.1/countries/states', { country });

      const stateNames = statesResponse.data.data.states.map(state => state.name);

      return {
        statusCode: 200,
        body: JSON.stringify(stateNames),
      };
    } else {
      console.log(event.path);
      return {
        statusCode: 400,
        body: JSON.stringify({ message: 'Invalid endpoint' })
      };
    }
  } catch (error) {
    console.error('Error:', error);
    return {
      statusCode: 500,
      body: JSON.stringify({ message: 'Internal Server Error' })
    };
  }
};

I want to be able to call GET on /countries to return all countries returned by the API I’m calling. I also want to be able to call POST on /states to return all states for a provided country. To be specific, I would like to be able to make the following API call:

POST ENDPOINT: `https://api-id.execute-api.region.amazonaws.com/develop/states`

BODY: {"country":"Canada"}

Currently, when I do this, I’m getting:

{
  "statusCode": 400,
  "body": "{"message":"Invalid endpoint"}"
}

That tells me that for some reason the endpoint is not being hit properly. Why is that? I’ve confirmed the endpoint states and countries are in the API Gateway. They also seem to be matching in the API call and the code. But perhaps there’s something I’m missing and I’m not using event.path correctly.

ADDITIONAL DETAIL BASED ON COMMENT BELOW:

I have logged the event and found it to be the following object:

{
    "version": "2.0",
    "routeKey": "POST /states",
    "rawPath": "/develop/states",
    "rawQueryString": "",
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "cache-control": "no-cache",
        "content-length": "26",
        "content-type": "application/json",
        "host": "cc1sxgjhi4.execute-api.us-east-1.amazonaws.com",
        "postman-token": "848e4596-d42d-4606-b84e-67ce27f05dfa",
        "user-agent": "PostmanRuntime/7.35.0",
        "x-amzn-trace-id": "Root=1-659800b6-5a35109603b2112664c29481",
        "x-forwarded-for": "142.112.6.191",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "requestContext": {
        "accountId": "624448452992",
        "apiId": "cc1sxgjhi4",
        "domainName": "cc1sxgjhi4.execute-api.us-east-1.amazonaws.com",
        "domainPrefix": "cc1sxgjhi4",
        "http": {
            "method": "POST",
            "path": "/develop/states",
            "protocol": "HTTP/1.1",
            "sourceIp": "142.112.6.191",
            "userAgent": "PostmanRuntime/7.35.0"
        },
        "requestId": "REUMkjYdIAMEVmQ=",
        "routeKey": "POST /states",
        "stage": "develop",
        "time": "05/Jan/2024:13:14:30 +0000",
        "timeEpoch": 1704460470586
    },
    "body": "{n  "country": "Canada"n}n",
    "isBase64Encoded": false
}

develop is the stage that I created on AWS and deployed the API Gateway on. I have tried the POST to https://api-id.execute-api.region.amazonaws.com/develop/states, https://api-id.execute-api.region.amazonaws.com/states and GET to https://api-id.execute-api.region.amazonaws.com/develop/countries, https://api-id.execute-api.region.amazonaws.com/countries

2

Answers


  1. Chosen as BEST ANSWER

    The issue was the event.path. I should have been calling an if on event.rawPath instead. Below is the full corrected code.

    import axios from 'axios';
    
    export const handler = async (event) => {
      try {
        console.log('EVENT');
        console.log(JSON.stringify(event, null, 2));
        if (event.rawPath === '/countries') {
          const countriesResponse = await axios.get('https://countriesnow.space/api/v0.1/countries/states');
    
          const countryNames = countriesResponse.data.data.map(country => country.name);
    
          return {
            statusCode: 200,
            body: JSON.stringify(countryNames),
          };
          
        } else if (event.rawPath === '/states') {
          const { country } = JSON.parse(event.body);
    
          const statesResponse = await axios.post('https://countriesnow.space/api/v0.1/countries/states', { country });
          console.log(statesResponse);
          const stateNames = statesResponse.data.data.states.map(state => state.name);
    
          return {
            statusCode: 200,
            body: JSON.stringify(stateNames),
          };
        } else {
          return {
            statusCode: 400,
            body: JSON.stringify({ message: 'Invalid endpoint' })
          };
        }
      } catch (error) {
        console.error('Error:', error);
        return {
          statusCode: 500,
          body: JSON.stringify({ message: 'Internal Server Error' })
        };
      }
    };
    

  2. Try to log the event object and see what is coming in it (Also add it in the question so that we can check further). It might probably have /develop/states instead of /states. If develop is something like a prefix and you don’t want to use it then you can try using event.resourcePath instead.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search