J'essaie de créer un exemple de bonjour le monde avec AWS lambda et de le servir via la passerelle api. J'ai cliqué sur "Créer une fonction Lambda", qui a configuré l'api gatway et sélectionné l'option Fonction vide. J'ai ajouté la fonction lambda présente dans Guide de démarrage rapide de la passerelle AWS :
exports.handler = function(event, context, callback) {
callback(null, {"Hello":"World"}); // SUCCESS with message
};
Le problème est que lorsque je lui adresse une requête GET, il renvoie une réponse 502 { "message": "Internal server error" }
. Et les journaux indiquent "L’exécution a échoué en raison d’une erreur de configuration: réponse du proxy Lambda mal formée".
Habituellement, lorsque vous voyez Malformed Lambda proxy response
, cela signifie que votre réponse de votre fonction Lambda ne correspond pas au format attendu par API Gateway, comme ceci
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Si vous n'utilisez pas l'intégration du proxy Lambda, vous pouvez vous connecter à la console API Gateway et désélectionner la case à cocher Intégration du proxy Lambda.
De même, si vous voyez un Malformed Lambda proxy response
intermittent, cela peut vouloir dire que la requête de votre fonction Lambda a été limitée par Lambda et que vous devez demander une augmentation simultanée de la limite d'exécution de la fonction Lambda.
Si lambda est utilisé comme proxy, le format de réponse doit être
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Oui, alors je pense que c'est parce que vous ne renvoyez pas une réponse http appropriée, ce qui explique pourquoi vous obtenez l'erreur.
personnellement, j'utilise un ensemble de fonctions telles que:
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.
Ensuite, vous faites simplement:
var responder = require('responder')
// some code
callback(null, responder.success({ message: 'hello world'}))
À partir de AWS docs
Dans une fonction Lambda dans Node.js, appelez .__ pour obtenir une réponse satisfaisante. callback (null, {"statusCode": 200, "body": "résultats"}). Lancer un exception, call callback (nouvelle erreur ('erreur interne du serveur')). Pour un erreur côté client, par exemple, si un paramètre requis est manquant, vous pouvez appeler callback (null, {"statusCode": 400, "body": "paramètres manquants de ..."}) pour retourner l'erreur sans lever d'exception.
Un cas très très spécial, si vous passez directement les en-têtes, il y a une chance que vous ayez cet en-tête:
"set-cookie": [ "........" ]
Mais Amazon a besoin de ceci:
"set-cookie": "[ \\"........\\" ]"
Pour quiconque se débat lorsque la réponse semble valide. Cela ne fonctionne pas:
callback(null,JSON.stringify( {
isBase64Encoded: false,
statusCode: 200,
headers: { 'headerName': 'headerValue' },
body: 'hello world'
})
mais cela fait:
callback(null,JSON.stringify( {
'isBase64Encoded': false,
'statusCode': 200,
'headers': { 'headerName': 'headerValue' },
'body': 'hello world'
})
En outre, il semble qu'aucune clé supplémentaire ne soit autorisée sur l'objet de réponse.
J'ai eu cette erreur parce que j'ai accidentellement supprimé la variable ServerlessExpressLambdaFunctionName de la ressource CloudFormation AWS :: Serverless :: Api. Le contexte ici est https://github.com/awslabs/aws-serverless-express "Exécuter des applications sans serveur et des API REST à l'aide de votre infrastructure d'application Node.js existante, au-dessus de AWS Lambda et Amazon API Gateway "
Si vous utilisez Go avec https://github.com/aws/aws-lambda-go , vous devez utiliser events.APIGatewayProxyResponse
.
func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
return events.APIGatewayProxyResponse{
IsBase64Encoded: false,
StatusCode: 200,
Headers: headers,
Body: body,
}, nil
}
J'ai essayé toutes les suggestions ci-dessus mais cela ne fonctionne pas alors que body
valeur n'est pas String
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
success: true
}),
isBase64Encoded: false
};
Une cause fréquente de l'erreur "Réponse incorrecte au proxy Lambda" est headers
qui ne sont pas des paires clé {String: String, ...}
.
Les en-têtes set-cookie
pouvant apparaître et apparaissant en multiples, ils sont représentés dans http.request.callback.response sous la forme de la clé set-cookie
ayant un Array
SUR Strings
valeur au lieu d'un single String
. Bien que cela fonctionne pour les développeurs, AWS API Gateway ne le comprend pas et génère une erreur "Réponse incorrecte au proxy Lambda".
Ma solution est de faire quelque chose comme ça:
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)
}
Notez que le ...
ci-dessus ne signifie pas Yada Yada Yada . C'est le opérateur de propagation ES6 .
Au cas où cela ne fonctionnerait pour personne, j’ai rencontré cette erreur malgré le réglage correct de la variable de réponse.
J'étais en train d'appeler une base de données RDS dans ma fonction. Il s’est avéré que les règles du groupe de sécurité (entrant) sur cette base de données étaient à l’origine du problème.
Vous voudrez probablement restreindre les adresses IP pouvant accéder à l'API, mais si vous voulez que cela fonctionne rapidement pour vérifier si cette modification le résout, vous pouvez le configurer pour qu'il accepte tous les utilisateurs similaires (vous pouvez également définir le paramètre sur les ports pour accepter tous les ports aussi, mais je ne l’ai pas fait dans cet exemple):