web-dev-qa-db-fra.com

en passant POST corps de la demande via Amazon API Gateway à Lambda

J'ai une fonction AWS Lambda écrite en Java, qui est déclenchée par un appel AWS API Gateway.

J'essaie de faire une demande POST à l'un des points de terminaison avec un JSON comme charge utile.

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

La passerelle va alors détecter le Content-Type et passez tous les paramètres de requête (y compris le corps) par défaut modèle . La partie intéressante est celle-ci

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

Il est censé me présenter un Map<String, Object> qui est passé à ma Java:

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

Et le résultat devrait être quelque chose comme ceci:

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

Mais ce que je reçois est le suivant:

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

Une autre possibilité serait de passer le corps entier en chaîne:

"body" : $input.body

mais encore une fois "convertit" simplement en key=value au lieu de key:value

Comment dois-je configurer le modèle pour simplement me passer le corps afin de pouvoir l'utiliser dans un analyseur JSON?

10
GameDroids

Et encore une fois - il suffit de poster une question ici sur SO aide à trouver la réponse par vous-même :)

Dans le modèle AWS Api Gateway, j'ai défini le corps sur

"body-json" : $input.body

qui devrait retourner la charge utile complète sous forme de chaîne.

Mais plus important encore, j'ai lu réponse de Greggs à sa propre question et changé ma méthode en

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());        
}

Donc, il suffit d'avoir un simple InputStream et de le lire comme JsonNode avec la bibliothèque JSON que l'on préfère (j'utilise Jackson FasterXML). Et le tour est joué, il regroupe tous les paramètres possibles dans un seul JSON (comme spécifié par le modèle)

{
    "body-json": {
        "firstName": "Mr",
        "lastName": "Awesome"
    },
    "params": {
       ...
    },
    "stage-variables": {
       ...
    },
    "context": {
        ...
    }
}
8
GameDroids