Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing POST request body through Amazon API Gateway to Lambda

I have a AWS Lambda function written in Java, that gets triggered by an AWS API Gateway call.

I am trying to make a POST request to one of the endpoints with a JSON as payload.

curl -H "Content-Type: application/json" -X POST -d '{"firstName":"Mr", "lastName":"Awesome"}' https://someexample.execute-api.eu-central-1.amazonaws.com/beta/MethodHandlerLambda

The gateway will then detect the Content-Type and pass all request parameters (including the body) through a default template. The interesting part is this one

#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
 ....

It is supposed to present me with a Map<String, Object> that is passed to my Java method:

public void myHandler(Map<String, Object> input, Context context){
    input.keySet().forEach((key) -> {
        System.out.println(key + " : " + input.get(key));
    });
}

And the result should be something like this:

body-json : {"firstName":"Mr", "lastName":"Awesome"}
...

But what I am getting is this:

body-json : {firstName=Mr, lastName=Awesome}

Another possibility would be to pass the whole body as string:

"body" : $input.body

but that again just "converts" to key=value instead of key:value

How do I have to configure the template to simply pass me the body so I can use it in a JSON parser?

like image 638
GameDroids Avatar asked Jun 27 '17 13:06

GameDroids


People also ask

What does API gateway pass to Lambda?

A Lambda integration maps a path and HTTP method combination to a Lambda function. You can configure API Gateway to pass the body of the HTTP request as-is (custom integration), or to encapsulate the request body in a document that includes all of the request information including headers, resource, path, and method.


1 Answers

And again - just posting a question here on SO helps to find the answer on your own :)

In the AWS Api Gateway template I set the body to

"body-json" : $input.body

which should return the complete payload as a String.

But more importantly I read Greggs answer to his own question and changed my method to

public void myHandler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException{
    final ObjectMapper objectMapper = new ObjectMapper();
    JsonNode json = objectMapper.readTree(inputStream);
    System.out.println(json.toString());        
}

So, it is sufficient to have a simple InputStream and read it as a JsonNode with whatever JSON library one prefers (I am using Jackson FasterXML). And voila, it packs all possible parameters in a single JSON (as specified by the template)

{
    "body-json": {
        "firstName": "Mr",
        "lastName": "Awesome"
    },
    "params": {
       ...
    },
    "stage-variables": {
       ...
    },
    "context": {
        ...
    }
}
like image 182
GameDroids Avatar answered Oct 02 '22 09:10

GameDroids