it-roy-ru.com

Ошибка шлюза лямбда-API AWS "Неправильный ответ лямбда-прокси"

Я пытаюсь создать пример Hello World с помощью AWS lambda и обслуживать его через шлюз API. Я нажал кнопку «Создать лямбда-функцию», в которой настраивался проход API, и выбрал опцию «Пустая функция». Я добавил лямбда-функцию, найденную в Руководство по началу работы со шлюзом AWS

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};

Проблема в том, что когда я делаю запрос GET, он возвращает ответ 502 { "message": "Internal server error" }. И в журналах написано «Выполнение не удалось из-за ошибки конфигурации: неправильный ответ Lambda прокси».

46
jjbskir

Обычно, когда вы видите Malformed Lambda proxy response, это означает, что ваш ответ от вашей функции Lambda не соответствует формату, ожидаемому API-шлюзом, как это

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

Если вы не используете интеграцию Lambda-прокси, вы можете войти в консоль API Gateway и снять флажок «Интеграция Lambda-прокси».

Кроме того, если вы видите прерывистый Malformed Lambda proxy response, это может означать, что запрос к вашей функции Lambda был ограничен Lambda, и вам нужно запросить увеличение ограничения одновременного выполнения для функции Lambda.

61
Ka Hou Ieong

Если в качестве прокси используется лямбда, то формат ответа должен быть

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

Примечание: тело должно быть строковым

31
selftaught91

Да, так что я думаю, что это потому, что вы на самом деле не возвращаете правильный HTTP-ответ, вот почему вы получаете ошибку.

лично я использую набор функций примерно так:

    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.

Тогда вы просто делаете:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))
20
Mrk Fldig

Из Документы AWS

В лямбда-функции в Node.js, чтобы вернуть успешный ответ, вызовите обратный вызов (null, {"statusCode": 200, "body": "results"}). Чтобы бросить исключение, обратный вызов (новая ошибка («внутренняя ошибка сервера»)). Для ошибка на стороне клиента, например, отсутствует обязательный параметр, вы можете вызвать обратный вызов (null, {"statusCode": 400, "body": "отсутствуют параметры ..."}) для возврата ошибки без исключения.

5
Jonathan

Очень особый случай, если вы передаете заголовки напрямую, есть вероятность, что у вас есть этот заголовок: 

"set-cookie": [ "........" ]

Но Амазону нужно это:

"set-cookie": "[ \\"........\\" ]"

2
Miguel

Для всех, кто борется, когда ответ кажется действительным. Это не работает:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})

но это делает:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})

Кроме того, кажется, что никакие дополнительные ключи не могут присутствовать на объекте ответа.

2
Ciryon

У меня была эта ошибка, потому что я случайно удалил переменную ServerlessExpressLambdaFunctionName из ресурса CloudFormation AWS :: Serverless :: Api. Контекст здесь: https://github.com/awslabs/aws-serverless-express "Запускать серверные приложения и REST API-интерфейсы с использованием существующей инфраструктуры приложений Node.js поверх AWS Lambda и Amazon API Gateway "

1
Mark

Если вы используете Go с https://github.com/aws/aws-lambda-go , вы должны использовать events.APIGatewayProxyResponse

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}
1
Kohei Mikami

Я испробовал все вышеизложенное предложение, но оно не работает, пока значение body не равно String

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};
0
Long Nguyen

Если вышеописанное не работает ни для кого, я столкнулся с этой ошибкой, несмотря на правильную настройку переменной response. 

Я выполнял вызов базы данных RDS в моей функции. Оказалось, что причиной проблемы были правила группы безопасности (входящие) в этой базе данных. 

Возможно, вы захотите ограничить IP-адреса, которые могут получить доступ к API, но если вы хотите, чтобы он работал быстро/грязно, чтобы проверить, исправит ли это изменение, вы можете настроить его на прием всех подобных параметров (вы также можете установить диапазон на портах, чтобы принять все порты также, но я не сделал этого в этом примере):

 enter image description here

0
abe732