1
votes

I have a Lambda function integrated with API Gateway and the stack was deployed as cloud formation template. When I try to test the endpoint in the AWS web console I got correct response but when I try to invoke the deployed version of the API I got that error.

"message": "Could not parse request body into json: Unrecognized token ....etc"

I tried this mapping { "body" : $input.json('$') } in the integration request, but didn't work.

Here is the JSON I am trying to send using POSTMAN

{
    "description": "test description",
    "status": "test status"
}

and the request has header: Content-Type: application/json

Here you are screenshots for POSTMAN request body & headers, and the response from the API:

enter image description here enter image description here

Any Solution guys?

UPDATE:

I put a mapping template at integration request level as the following:

{
   "body-json" : $input.json('$')
}

And updated the lambda function to log the coming request, then made 2 requests:

First one: from API Gateway test web console:

I found the following in the cloudwatch logs:

INFO    {
  body: {
    description: 'test',
    projectId: 23,
    action: 'test',
    entity: 'test',
    startDate: '01-01-2020',
    endDate: '01-01-2020'
  }
}

Second one: from POSTMAN:

I found the following in the cloudwatch logs:

INFO    {
  body: 'ewogICAgImRlc2NyaXB0aW9uIjogInRlc3QiLAogICAgInByb2plY3RJZCI6IDIzLAogICAgImFjdGlvbiI6ICJ0ZXN0IiwKICAgICJlbnRpdHkiOiAidGVzdCIsCiAgICAic3RhcnREYXRlIjogIjAxLTAxLTIwMjAiLAogICAgImVuZERhdGUiOiAiMDEtMDEtMjAyMCIKfQ=='
}

That indicates that in case of making the request using POSTMAN, the JSON payload is stringified automatically. What can cause such thing? and how to deal with it?

2
Comments are not for extended discussion; this conversation has been moved to chat. - Samuel Liew♦
Can you also share the relevant snippet from yaml/json of the CloudFormation template? - Sarthak Jain

2 Answers

3
votes

In this case we need to edit the mapping template since we are not using a proxy integration.

"body-json" : $input.json('$')
//also if binary data type is enabled for your api your body will be a base64
//encoded string which could be decoded using
$util.base64Decode($input.json('$'))

Also binary data types maybe enabled by default, search for these in the SAM template

x-amazon-apigateway-binary-media-types:
- '*/*'
0
votes

You need to add a custom header in your response for it to respond correctly.

  // The output from a Lambda proxy integration must be 
  // in the following JSON object. The 'headers' property 
  // is for custom response headers in addition to standard 
  // ones. The 'body' property  must be a JSON string. For 
  // base64-encoded payload, you must also set the 'isBase64Encoded'
  // property to 'true'.
  let response = {
      statusCode: responseCode,
      headers: {
          "x-custom-header" : "my custom header value"
      },
      body: JSON.stringify(responseBody)
  };