1
votes

I have a POST API setup with Lambda Proxy integration turned on. My Lambda function is in Java here:

 public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
         
          //log some stuff
          Gson gson = new GsonBuilder().setPrettyPrinting().create();
          LambdaLogger logger = context.getLogger();
          logger.log("Method Start " +input );
          logger.log("CONTEXT: " + gson.toJson(context));
          
          //Initialize response and DB
          logger.log("Inizialize response and DB " );
          APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
          dynamoDb = new DynamoDB(client);
          
          try {
              logger.log("Getting REST method type " );
              String restMethod = input.getHttpMethod();
              logger.log("REST method type " +restMethod);
              logger.log("Input body: "+input.getBody());
              
              if (restMethod.equals("POST")) {
                  logger.log("POST method Start " );
                  String requestString = input.getBody();
                  JSONParser parser = new JSONParser();
                  JSONObject requestJsonObject = (JSONObject) parser.parse(requestString);
                  String name = requestJsonObject.get("name").toString();
                  logger.log("Before DB call " );
                  sendDataToDb(name, response);
                  logger.log("POST code End " );
              }
              if (restMethod.equals("GET")) {
                 logger.log("GET method Start " );
                 Map<String,String>pathParameters = input.getPathParameters();
                 String name2 = pathParameters.get("name");
                 getDataFromDb(name2, response);
              }
              
          } catch(Exception e){
              response.setStatusCode(405);
              response.setBody("exception Thrown");
              logger.log("Exception: " +e);
          }

          return response;
      }

I can send POST API requests via the AWS Lambda and API Gateway consoles and it works perfectly fine. I get my response and the API/Lambda function perfectly. But anytime I try to send the same POST API via curl or postman or a javascript fetch, my Lambda is receiving null as the APIGatewayProxyRequestEvent.

Here is an example javascript I was testing:

    <script>
        // define the callAPI function that takes a first name and last name as parameters
        var callPostAPI = (name)=>{
            // instantiate a headers object
            var myHeaders = new Headers();
            // add content type header to object
            myHeaders.append("Content-Type", "application/json");
            // using built in JSON utility package turn object to string and store in a variable
            var raw = JSON.stringify({"name":name});
            // create a JSON object with parameters for API call and store in a variable
            var requestOptions = {
                resource: '/',
                path:'/',
                httpMethod: 'POST',
                headers: myHeaders,
                multiValueHeaders: 'X-Forwarded-Proto=[https]',
                queryStringParameters: '{}',
                multiValueQueryStringParameters: '{}',
                pathParameters: '{proxy=}',
                stageVariables: '{baz=qux}',
                requestContext: '{accountId: 123456789012,resourceId: 123456,stage: prod,requestId: c6af9ac6-7b61-11e6-9a41-93e8deadbeef,identity: {sourceIp: 127.0.0.1,userAgent: Custom User Agent String,},resourcePath: /{proxy+},httpMethod: POST,apiId: 1234567890,path: /prod/path/to/resource,}',
                body: raw,
                isBase64Encoded: false,
                method: 'POST',
                redirect: 'follow'
            };
            // make API call with parameters and use promises to get response
            fetch("https://t3fl0anfw2.execute-api.us-east-1.amazonaws.com/dev", requestOptions)
            .then(response => response.text())
            .then(result => alert(JSON.parse(result).body))
            .catch(error => console.log('error', error));
        }
        
    </script>

So I know it works via AWS console but I cannot get it to work from anything outside these consoles. Is there a particular format I should be sending these API requests in? I tried to copy the same format the Lambda/APIGateway consoles were sending in, but no luck. I can't seem to find any documentation on this specific use case, so any help is appreciated.

1
Are you getting any CORS errors when attempting the call from Javascript? - Jack Marchetti
Yes I'm seeing Access to fetch at **** has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. - SuzukaSteve

1 Answers

0
votes

So you might be running into CORS issues.

You need to enable CORS in the API Gateway, and then you need to also include CORS headers in the response from your API Gateway Response. (including it in the actual response is often overlooked, so make sure you do that)

response = {
        statusCode: 200,
        **headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "https://www.example.com",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
        },**
        body: JSON.stringify('Example'),
    };
    return response;
};

https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html