web-dev-qa-db-ja.com

AWSラムダAPIゲートウェイエラー「Malformed Lambda proxy response」

AWS lambdaを使用してHello Worldの例をセットアップし、APIゲートウェイを介して提供しようとしています。 「Create a Lambda Function」をクリックして、API gatwayをセットアップし、「Blank Function」オプションを選択しました。 AWSゲートウェイスタートガイド :にあるラムダ関数を追加しました。

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

問題は、GET要求を行うと、502応答{ "message": "Internal server error" }が返されることです。また、ログには「構成エラーのため実行に失敗しました:不正なLambdaプロキシ応答」と表示されます。

58
jjbskir

通常、Malformed Lambda proxy responseが表示される場合、Lambda関数からの応答がAPI Gatewayが期待している形式と一致しないことを意味します。

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

Lambdaプロキシ統合を使用していない場合は、API Gatewayコンソールにログインし、Lambdaプロキシ統合チェックボックスをオフにすることができます。

また、断続的なMalformed Lambda proxy responseが表示される場合、Lambda関数へのリクエストがLambdaによって調整されている可能性があり、Lambda関数の同時実行制限の増加を要求する必要があります。

75
Ka Hou Ieong

ラムダがプロキシとして使用される場合、応答形式は

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

注:本文は文字列化する必要があります

38
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'}))
23
Mrk Fldig

AWS docs から

Node.jsのLambda関数で、成功した応答を返すには、callback(null、{"statusCode":200、 "body": "results"})を呼び出します。例外をスローするには、callback(new Error( 'internal server error'))を呼び出します。クライアント側のエラー、たとえば必須パラメーターが欠落している場合、callback(null、{"statusCode":400、 "body": "Missing parameters of ..."})を呼び出して、スローせずにエラーを返すことができます。例外。

6
Jonathan

非常に特殊なケースです。ヘッダーを直接渡すと、このヘッダーがある可能性があります。

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

しかし、Amazonにはこれが必要です。

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

3
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'
})

また、応答オブジェクトに余分なキーを含めることは許可されていないようです。

3
Ciryon

https://github.com/aws/aws-lambda-go で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
}
3
Kohei Mikami

CloudFormation AWS :: Serverless :: Apiリソースから誤って変数ServerlessExpressLambdaFunctionNameを削除したため、このエラーが発生しました。ここでのコンテキストは https://github.com/awslabs/aws-serverless-express "既存のNode.jsアプリケーションフレームワークを使用して、サーバーレスアプリケーションとREST_ APIを実行します。 AWS LambdaとAmazon API Gatewayの」

1
Mark

上記の提案をすべて試してみましたが、body値がStringではない間は機能しません

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

「Malformed Lambda proxy response」エラーの一般的な原因は、{String: String, ...}キー/値ペアではないheadersです。

set-cookieヘッダーは複数で表示される可能性があるため、http.request.callback.responseでは、-ではなくArray OF Strings値を持つset-cookieキーとして表されます。 単一のString。これは開発者には有効ですが、AWS API Gatewayはそれを理解せず、「Malformed Lambda proxy response」エラーをスローします。

私の解決策は、このようなことをすることです:

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)
}

上記の...Yada Yada Yadaを意味しないことに注意してください。 ES6スプレッド演算子 です。

0
Bruno Bronosky

上記の方法が誰にも当てはまらない場合、応答変数を正しく設定してもこのエラーに遭遇しました。

関数内でRDSデータベースを呼び出していました。問題の原因は、そのデータベースのセキュリティグループルール(受信)であることが判明しました。

おそらく、APIにアクセスできるIPアドレスを制限することをお勧めしますが、変更を修正するかどうかをテストするためにすばやく/ダーティに動作させたい場合は、そのようにすべて受け入れるように設定できます(また、ポートの範囲もすべてのポートを受け入れるようにしますが、この例ではそうしませんでした):

enter image description here

0
abe732