108 votes

Obtenir le corps json dans aws Lambda via une passerelle API

Je suis actuellement à l'aide de NodeJS pour construire un robot sur AWS lambda via Api AWS porte d'entrée et je suis en cours d'exécution dans un problème avec les requêtes POST et les données JSON. Mon api utilise 'Utilisation Lambda Proxy intégration" et même quand j'ai tester le proxy de l'envoi d'un type de contenu Application/json et certains json dans le corps de l'e.g {"foo":"bar"} je ne peux pas accéder à l'objet sans l'analyser en premier

e.g

  var json = JSON.parse(event.body);
  console.log(json.foo);

Maintenant, je sais que ce ne pas sembler une grosse affaire, juste en cours d'exécution à travers JSON.analyser, mais j'ai vu un certain nombre d'autres exemples où ce n'est pas du tout le cas. voir ici https://github.com/pinzler/fb-messenger-bot-aws-lambda/blob/master/index.js

Dois-je besoin d'ajouter quelque chose à ma passerelle API pour gérer cela correctement? mon "corps de la requête' étape dans la "méthode post de demande à la section" a un type de contenu application/json set-up pour le corps de la requête.

Le fichier readme pour l'exemple ci-dessus ne semble pas utiliser le proxy de l'intégration que je peux dire, donc je ne suis pas sûr de ce que je devrais faire ici

97voto

Ka Hou Ieong Points 2168

Il existe deux types de Lambda intégrations vous pouvez configurer la Passerelle API, comme le Lambda de l'intégration et de Lambda proxy de l'intégration. Pour Lambda intégration, vous pouvez personnaliser ce que vous allez passer à Lambda dans la charge utile et que vous n'avez pas besoin d'analyser le corps, mais lorsque vous utilisez Lambda Proxy intégration dans la Passerelle API, API Passerelle proxy tout à Lambda en charge de ce genre,

{
    "message": "Hello me!",
    "input": {
        "path": "/test/hello",
        "headers": {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
            "Accept-Language": "en-US,en;q=0.8",
            "CloudFront-Forwarded-Proto": "https",
            "CloudFront-Is-Desktop-Viewer": "true",
            "CloudFront-Is-Mobile-Viewer": "false",
            "CloudFront-Is-SmartTV-Viewer": "false",
            "CloudFront-Is-Tablet-Viewer": "false",
            "CloudFront-Viewer-Country": "US",
            "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
            "Upgrade-Insecure-Requests": "1",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
            "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
            "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
            "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
            "X-Forwarded-Port": "443",
            "X-Forwarded-Proto": "https"
        },
        "pathParameters": {"proxy": "hello"},
        "requestContext": {
            "accountId": "123456789012",
            "resourceId": "us4z18",
            "stage": "test",
            "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
            "identity": {
                "cognitoIdentityPoolId": "",
                "accountId": "",
                "cognitoIdentityId": "",
                "caller": "",
                "apiKey": "",
                "sourceIp": "192.168.100.1",
                "cognitoAuthenticationType": "",
                "cognitoAuthenticationProvider": "",
                "userArn": "",
                "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
                "user": ""
            },
            "resourcePath": "/{proxy+}",
            "httpMethod": "GET",
            "apiId": "wt6mne2s9k"
        },
        "resource": "/{proxy+}",
        "httpMethod": "GET",
        "queryStringParameters": {"name": "me"},
        "stageVariables": {"stageVarName": "stageVarValue"},
        "body": "{\"foo\":\"bar\"}",
        "isBase64Encoded": false
    }
}

Pour l'exemple que vous faites référence, il n'est pas le corps de la demande originale. Il est en train de construire le corps de la réponse de retour à la Passerelle API. Il devrait être dans ce format,

{
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "...",
    "isBase64Encoded": false
}

76voto

mon Points 1271

Je pense qu'il y a peu de choses à comprendre lorsque l'on travaille avec des API d'intégration de la Passerelle avec Lambda.

Lambda Intégration vs Lambda Proxy Intégration

Il y avait seulement Lambda Intégration qui exige une cartographie des modèles. Je suppose que c'est pourquoi encore voir de nombreux exemples de l'utiliser.

  • Comment passer d'une chaîne de requête ou un paramètre de route pour AWS Lambda de Passerelle API Amazon

    En septembre 2017, vous n'avez plus à configurer les mappages d'accéder à la demande du corps.

  • Sans serveur de l'Architecture sur AWS

    Lambda Proxy Intégration, Si vous l'activez, l'API Gateway carte chaque requête JSON et le transmettre à l'Lambda comme l'objet de l'événement. Dans la fonction Lambda, vous serez en mesure de récupérer les paramètres de chaîne de requête, les en-têtes de, stade de variables, chemin des paramètres, contexte de demande, et le corps.

    Sans l'activation de Lambda Proxy Intégration, vous aurez pour créer un modèle de mappage dans l'Intégration de la section de Demande de Passerelle API et de décider de la façon de carte de la requête HTTP en JSON vous-même. Et vous auriez probablement à créer une Intégration de la Réponse de la cartographie si vous passer l'information au client.

    Avant Lambda Proxy Intégration a été ajouté, les utilisateurs ont été contraints de faire correspondre les requêtes et les réponses manuellement, ce qui était une source de consternation, surtout avec plus de mappings.

le corps est échappé de chaîne, pas de JSON

En utilisant la Lambda Proxy de l'Intégration, le corps dans le cas de la lambda est une chaîne de caractères échappés avec une barre oblique inverse, pas un JSON.

"body": "{\"foo\":\"bar\"}" 

Si l'essai dans un JSON formateur.

Parse error on line 1:
{\"foo\":\"bar\"}
-^
Expecting 'STRING', '}', got 'undefined'

Le document ci-dessous est à propos de la réponse, mais il doit s'appliquer à la demande.

Pour le JavaScript pour accéder à un objet JSON, besoin de la convertir en objet JSON json.analyser dans JapaScript, json.les décharges en Python.

  • Comment Travailler avec JSON en JavaScript

    Les chaînes sont utiles pour le transport, mais vous aurez envie d'être capable de les convertir en arrière à un objet JSON sur le client et/ou du côté serveur.

L' AWS documentation montre comment faire.

if (event.body !== null && event.body !== undefined) {
    let body = JSON.parse(event.body)
    if (body.time) 
        time = body.time;
}
...
var response = {
    statusCode: responseCode,
    headers: {
        "x-custom-header" : "my custom header value"
    },
    body: JSON.stringify(responseBody)
};
console.log("response: " + JSON.stringify(response))
callback(null, response);

2voto

Te ENe Te Points 82

Je suis en utilisant la lambda avec Zappa; Je suis d'envoyer des données en POST, au format json:

Mon code pour les basic_lambda_pure.py est:

import time
import requests
import json
def my_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    print("Log stream name:", context.log_stream_name)
    print("Log group name:",  context.log_group_name)
    print("Request ID:", context.aws_request_id)
    print("Mem. limits(MB):", context.memory_limit_in_mb)
    # Code will execute quickly, so we add a 1 second intentional delay so you can see that in time remaining value.
    print("Time remaining (MS):", context.get_remaining_time_in_millis())

    if event["httpMethod"] == "GET":
        hub_mode = event["queryStringParameters"]["hub.mode"]
        hub_challenge = event["queryStringParameters"]["hub.challenge"]
        hub_verify_token = event["queryStringParameters"]["hub.verify_token"]
        return {'statusCode': '200', 'body': hub_challenge, 'headers': 'Content-Type': 'application/json'}}

    if event["httpMethod"] == "post":
        token = "xxxx"
    params = {
        "access_token": token
    }
    headers = {
        "Content-Type": "application/json"
    }
        _data = {"recipient": {"id": 1459299024159359}}
        _data.update({"message": {"text": "text"}})
        data = json.dumps(_data)
        r = requests.post("https://graph.facebook.com/v2.9/me/messages",params=params, headers=headers, data=data, timeout=2)
        return {'statusCode': '200', 'body': "ok", 'headers': {'Content-Type': 'application/json'}}

J'ai eu de la prochaine réponse json:

{
"resource": "/",
"path": "/",
"httpMethod": "POST",
"headers": {
"Accept": "*/*",
"Accept-Encoding": "deflate, gzip",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Content-Type": "application/json",
"Host": "ox53v9d8ug.execute-api.us-east-1.amazonaws.com",
"Via": "1.1 f1836a6a7245cc3f6e190d259a0d9273.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "LVcBZU-YqklHty7Ii3NRFOqVXJJEr7xXQdxAtFP46tMewFpJsQlD2Q==",
"X-Amzn-Trace-Id": "Root=1-59ec25c6-1018575e4483a16666d6f5c5",
"X-Forwarded-For": "69.171.225.87, 52.46.17.84",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https",
"X-Hub-Signature": "sha1=10504e2878e56ea6776dfbeae807de263772e9f2"
},
"queryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"path": "/dev",
"accountId": "001513791584",
"resourceId": "i6d2tyihx7",
"stage": "dev",
"requestId": "d58c5804-b6e5-11e7-8761-a9efcf8a8121",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"apiKey": "",
"sourceIp": "69.171.225.87",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": null,
"user": null
},
"resourcePath": "/",
"httpMethod": "POST",
"apiId": "ox53v9d8ug"
},
"body": "eyJvYmplY3QiOiJwYWdlIiwiZW50cnkiOlt7ImlkIjoiMTA3OTk2NDk2NTUxMDM1IiwidGltZSI6MTUwODY0ODM5MDE5NCwibWVzc2FnaW5nIjpbeyJzZW5kZXIiOnsiaWQiOiIxNDAzMDY4MDI5ODExODY1In0sInJlY2lwaWVudCI6eyJpZCI6IjEwNzk5NjQ5NjU1MTAzNSJ9LCJ0aW1lc3RhbXAiOjE1MDg2NDgzODk1NTUsIm1lc3NhZ2UiOnsibWlkIjoibWlkLiRjQUFBNHo5RmFDckJsYzdqVHMxZlFuT1daNXFaQyIsInNlcSI6MTY0MDAsInRleHQiOiJob2xhIn19XX1dfQ==",
"isBase64Encoded": true
}

mes données était sur le corps de la clé, mais est code64 codé, Comment puis-je le savoir? J'ai vu la clé isBase64Encoded

Je copie la valeur pour les corps de la clé et de décoder avec Cet outil et "eureka", j'obtiens les valeurs.

J'espère que cela vous aidera. :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X