Ich versuche, mit AWS Lambda ein Hallo-Welt-Beispiel zu erstellen und es über das API-Gateway bereitzustellen. Ich klickte auf "Eine Lambda-Funktion erstellen", wodurch das API-Gateway eingerichtet und die Option "Leere Funktion" ausgewählt wurde. Ich habe die Lambda-Funktion hinzugefügt, die in der Anleitung zum Einstieg in das AWS-Gateway enthalten ist :
exports.handler = function(event, context, callback) {
callback(null, {"Hello":"World"}); // SUCCESS with message
};
Das Problem ist, dass bei einer GET-Anfrage eine 502-Antwort zurückgegeben wird { "message": "Internal server error" }
. In den Protokollen wird angezeigt, dass die Ausführung aufgrund eines Konfigurationsfehlers fehlgeschlagen ist: Fehlerhafte Lambda-Proxy-Antwort.
Wenn Lambda als Proxy verwendet wird, sollte das Antwortformat sein
{ "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... }, "body": "..." }
Hinweis: Der Körper sollte stringifiziert sein
quelle
callback(null,response);
statusCode
erforderlich, damit ein Aufruf von API Gateway erfolgreich ist.Ja, ich denke, das liegt daran, dass Sie dort keine richtige http-Antwort zurückgeben, weshalb Sie den Fehler erhalten.
persönlich benutze ich eine Reihe von Funktionen wie folgt:
module.exports = { success: (result) => { return { statusCode: 200, headers: { "Access-Control-Allow-Origin" : "*", // Required for CORS support to work "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS }, body: JSON.stringify(result), } }, internalServerError: (msg) => { return { statusCode: 500, headers: { "Access-Control-Allow-Origin" : "*", // Required for CORS support to work "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS }, body: JSON.stringify({ statusCode: 500, error: 'Internal Server Error', internalError: JSON.stringify(msg), }), } } } // add more responses here.
Dann machst du einfach:
var responder = require('responder') // some code callback(null, responder.success({ message: 'hello world'}))
quelle
Aus den AWS-Dokumenten
quelle
Für Python3:
import json def lambda_handler(event, context): return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps({ 'success': True }), "isBase64Encoded": False }
Beachten Sie, dass das
body
nicht festgelegt werden muss, sondern nur leer sein kann:'body': ''
quelle
Ein ganz besonderer Fall, wenn Sie die Header direkt übergeben, besteht die Möglichkeit, dass Sie diesen Header haben:
"set-cookie": [ "........" ]
Aber Amazon braucht das:
"set-cookie": "[ \\"........\\" ]"
quelle
Für alle anderen, die Probleme haben, wenn die Antwort gültig erscheint. Das funktioniert nicht:
callback(null,JSON.stringify( { isBase64Encoded: false, statusCode: 200, headers: { 'headerName': 'headerValue' }, body: 'hello world' })
aber das tut:
callback(null,JSON.stringify( { 'isBase64Encoded': false, 'statusCode': 200, 'headers': { 'headerName': 'headerValue' }, 'body': 'hello world' })
Es scheint auch, dass keine zusätzlichen Schlüssel auf dem Antwortobjekt vorhanden sein dürfen.
quelle
Wenn Sie Go mit https://github.com/aws/aws-lambda-go verwenden , müssen Sie verwenden
events.APIGatewayProxyResponse
.func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) { return events.APIGatewayProxyResponse{ IsBase64Encoded: false, StatusCode: 200, Headers: headers, Body: body, }, nil }
quelle
Ich habe alle oben genannten Vorschläge ausprobiert, aber es funktioniert nicht, während der
body
Wert nicht istString
return { statusCode: 200, headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }, body: JSON.stringify({ success: true }), isBase64Encoded: false };
quelle
Nur ein Stück Code für .net Core und C # :
using Amazon.Lambda.APIGatewayEvents; ... var response = new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = JsonConvert.SerializeObject(new { msg = "Welcome to Belarus! :)" }), Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } } }; return response;
Die Antwort von Lambda lautet:
{"statusCode":200,"headers":{"Content-Type":"application/json"},"multiValueHeaders":null,"body":"{\"msg\":\"Welcome to Belarus! :)\"}","isBase64Encoded":false}
Die Antwort vom API-Gateway lautet:
{"msg":"Welcome to Belarus! :)"}
quelle
Ich hatte diesen Fehler, weil ich versehentlich die Variable ServerlessExpressLambdaFunctionName aus der CloudFormation AWS :: Serverless :: Api-Ressource entfernt habe. Der Kontext hier ist https://github.com/awslabs/aws-serverless-express "Führen Sie serverlose Anwendungen und REST-APIs mit Ihrem vorhandenen Node.js-Anwendungsframework über AWS Lambda und Amazon API Gateway aus."
quelle
Falls das oben genannte für niemanden funktioniert, ist dieser Fehler aufgetreten, obwohl die Antwortvariable korrekt eingestellt wurde.
Ich habe in meiner Funktion eine RDS-Datenbank aufgerufen. Es stellte sich heraus, dass das Problem die Sicherheitsgruppenregeln (eingehend) in dieser Datenbank verursachte.
Sie möchten wahrscheinlich die IP-Adressen einschränken, die auf die API zugreifen können, aber wenn Sie möchten, dass sie schnell / schmutzig funktioniert, um zu testen, ob diese Änderung das Problem behebt, können Sie festlegen, dass sie alle so akzeptieren (Sie können auch die festlegen Bereich an den Ports, um auch alle Ports zu akzeptieren, aber das habe ich in diesem Beispiel nicht getan):
quelle
Eine häufige Ursache für den Fehler "Fehlgebildete Lambda-Proxy-Antwort" ist,
headers
dass es sich nicht um{String: String, ...}
Schlüssel / Wert-Paare handelt.Da
set-cookie
Header und im mehrfachen erscheinen, werden sie in http.request.callback.response als der dargestelltenset-cookie
Schlüssel ein mitArray
derStrings
anstelle eines Wertes EinzelString
. Während dies für Entwickler funktioniert, versteht AWS API Gateway es nicht und gibt den Fehler "Fehlgebildete Lambda-Proxy-Antwort" aus.Meine Lösung besteht darin, so etwas zu tun:
function createHeaders(headers) { const singleValueHeaders = {} const multiValueHeaders = {} Object.entries(headers).forEach(([key, value]) => { const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders Object.assign(targetHeaders, { [key]: value }) }) return { headers: singleValueHeaders, multiValueHeaders, } } var output = { ...{ "statusCode": response.statusCode, "body": responseString }, ...createHeaders(response.headers) }
Beachten Sie, dass das
...
oben Gesagte nicht Yada Yada Yada bedeutet . Es ist der ES6-Spread-Operator .quelle
Hier ist ein anderer Ansatz. Konfigurieren Sie die Zuordnungsvorlage in Ihrer API-Gateway-Integrationsanforderung und -Antwort. Gehen Sie zu IntegrationRequest -> MappingTemplate -> wählen Sie "Wenn keine Vorlagen definiert sind" -> geben Sie application / json als Inhaltstyp ein. Dann müssen Sie keinen Json explizit senden. Sogar die Antwort, die Sie bei Ihrem Kunden erhalten, kann eine einfache Zeichenfolge sein.
quelle
Das Format Ihrer Funktionsantwort ist die Ursache für diesen Fehler. Damit API Gateway die Antwort einer Lambda-Funktion verarbeiten kann, muss die Antwort JSON in diesem Format sein:
{"isBase64Encoded": true | false, "statusCode": httpStatusCode, "headers": {"headerName": "headerValue", ...}, "body": "..."}
Hier ist eine Beispielfunktion in Node.js mit der korrekt formatierten Antwort:
exports.handler = (Ereignis, Kontext, Rückruf) => {
var responseBody = { "key3": "value3", "key2": "value2", "key1": "value1" }; var response = { "statusCode": 200, "headers": { "my_header": "my_value" }, "body": JSON.stringify(responseBody), "isBase64Encoded": false }; callback(null, response);
};
Ref: https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/
quelle
Python 3.7
Vor
{ "isBase64Encoded": False, "statusCode": response.status_code, "headers": { "Content-Type": "application/json", }, "body": response.json() }
Nach
{ "isBase64Encoded": False, "statusCode": response.status_code, "headers": { "Content-Type": "application/json", }, "body": str(response.json()) //body must be of string type }
quelle
Wenn Sie AWS noch nicht kennen und nur möchten, dass Ihre URL funktioniert,
Wenn Sie keinen Trigger für Ihre Lambda-Funktion erstellt haben, navigieren Sie zu der Funktion in der Lambda-Funktions-App und erstellen Sie einen Trigger, indem Sie API Gateway auswählen.
Navigieren Sie zu API Gateway App -> Wählen Sie das API-Gateway Ihres bestimmten Lambda aus (Methodenausführung) -> Klicken Sie auf INTEGRATION Request -> Deaktivieren Sie "Use Lambda Proxy Integration". .
Klicken Sie dann auf " <-Method Execution " und dann auf den Abschnitt Test Client. Geben Sie die Optionen ein und klicken Sie auf die Schaltfläche Test. Sie sollten eine Erfolgsantwort sehen.
Wenn Sie immer noch keine Erfolgsantwort erhalten können, erstellen Sie einen Alias für die richtige Version (wenn die Lambda-Funktion mehrere Versionen enthält).
Wählen Sie die URL aus den Protokollen aus, verwenden Sie Ihr POST / GET-Tool (Postman) und wählen Sie die Authentifizierung als AWS-Signatur. Geben Sie Ihre Authentifizierungsschlüssel (AccessKey & SecretKey) in der Postman-Anfrage mit AWS Region & Service Name als Lambda an.
PS: Dies kann nur Anfängern helfen und für andere irrelevant sein.
quelle