J'ai cette fonction lambda python
import json def lambda_handler(event, context): post_user = "" post_user = event["user"] print(post_user) return { "statusCode": 200, "headers": {"Content-Type": "application/json"}, "body": True }
Cela fonctionne comme prévu lorsque j'exécute un test dans l'IDE lambda. Le test est configuré pour réussir:
{"utilisateur": "JOHN", "pwd": "pwd1"}
mais lorsque j'exécute un test en utilisant la passerelle API, j'obtiens cette erreur:
Mon 25 mars 20:47:29 UTC 2019: corps de réponse du point de terminaison avant transformations: {"errorMessage": "'user'", "errorType": "KeyError", "stackTrace": ["File \" / var / task / lambda_function.py \ ", ligne 6, dans lambda_handler \ n post_user = event [\ "user \"] \ n "]} Mon 25 mars 20:47:29 UTC 2019: l'exécution de Lambda a échoué avec l'état 200 en raison de erreur de fonction client: «utilisateur». ID de demande Lambda: f7955f74-e608-4b10-b216-4e4acf682307 Mon Mar 25 20:47:29 UTC 2019: Méthode terminée avec le statut: 502
3 Réponses :
En effet, lorsque l'objet event
provient d'API Gateway, il contient des informations supplémentaires. Ce n'est pas aussi simple que le JSON que vous utilisez pour tester depuis la console.
Vous devez d'abord accéder à l'objet body
, puis enfin à votre objet JSON.
Voici comment un L'événement d'API Gateway ressemble à:
{ "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": "'{\"user\":\"john\",\"pwd\":\"pwd1\"}'" }
Gardez à l'esprit que le body
d'API Gateway est toujours stringifié, donc si vous souhaitez y accéder, vous devez d'abord analyser cette chaîne JSON en utilisant json.loads(event["body" )
.
N'oubliez pas que le corps de votre réponse doit être Stringified lors du retour à API Gateway, comme nous l'avons vu sur cette réponse .
Vous pouvez voir le événement envoyé depuis API Gateway dans la docs a>
@Thales Minussi m'a conduit à cette réponse, mais la clé que j'obtiens de la réponse est différente de ce qu'il a suggéré, mais sa suggestion est ce qui m'a aidé donc je l'accepte comme réponse
J'obtenais cette réponse . La clé body
arrive sous la forme null
. mais il y avait des queryStringParameters
import json def lambda_handler(event, context): json_data = event["queryStringParameters"] user = json_data["user"] return { "statusCode": 200, "headers": {"Content-Type": "application/json"}, "body": json.dumps(user) }
J'ai changé ma fonction en
{ "resource": "/match_creds", "path": "/match_creds", "httpMethod": "GET", "headers": null, "multiValueHeaders": null, "queryStringParameters": { "pwd": "pwd1", "user": "JOHN" }, "multiValueQueryStringParameters": { "pwd": [ "pwd1" ], "user": [ "JOHN" ] }, "pathParameters": null, "stageVariables": null, "requestContext": { "path": "/match_creds", "accountId": "", "resourceId": "", "stage": "test-invoke-stage", "domainPrefix": "testPrefix", "requestId": "", "identity": { "cognitoIdentityPoolId": null, "cognitoIdentityId": null, "apiKey": "test-invoke-api-key", "cognitoAuthenticationType": null, "userArn": "", "apiKeyId": "test-invoke-api-key-id", "userAgent": "", "accountId": "", "caller": "", "sourceIp": "test-invoke-source-ip", "accessKey": "", "cognitoAuthenticationProvider": null, "user": "" }, "domainName": "testPrefix.testDomainName", "resourcePath": "/match_creds", "httpMethod": "GET", "extendedRequestId": "", "apiId": "" }, "body": null, "isBase64Encoded": false }
Agréable. Je marquerais la vôtre comme acceptée car elle reflète mieux la réalité. J'ai oublié que c'était dans les paramètres de requête, mais je suis heureux d'avoir pu aider d'une manière ou d'une autre.
Vous devez activer le paramètre "Utiliser l'intégration du proxy Lambda" sous "Demande d'intégration".
Pourquoi mettriez-vous l'instruction return dans un bloc try / except?
il y avait un tas de code là-bas mais je me suis débarrassé avant de poster ici. Je vais le supprimer pour éviter toute confusion.
Enregistrez simplement l'événement et voyez ce que vous obtenez, vous pouvez utiliser `somedict.get ('somekey') pour accéder à une clé sans déclencher d'exception. Si la clé n'existe pas, elle renvoie None
Si vous utilisez l'intégration de proxy, vous recevrez l'événement avec une structure différente: docs.aws.amazon.com/apigateway/latest/developerguide/...