AWS Lambda API 게이트웨이 오류 "잘못된 Lambda 프록시 응답"


85

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 프록시 응답"이라고 표시됩니다.

답변:


113

일반적 Malformed Lambda proxy response으로이 표시되면 Lambda 함수의 응답이 다음과 같이 API Gateway가 예상하는 형식과 일치하지 않음을 의미합니다.

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

Lambda 프록시 통합을 사용하지 않는 경우 API Gateway 콘솔에 로그인하고 Lambda 프록시 통합 확인란을 선택 취소 할 수 있습니다.

또한 intermittent Malformed Lambda proxy response가 표시되는 경우 Lambda 함수에 대한 요청이 Lambda에 의해 조절되었음을 의미 할 수 있으며 Lambda 함수에 대한 동시 실행 제한 증가를 요청해야합니다.



4
여기에 대한 AWS 지원 기사가 있습니다. aws.amazon.com/premiumsupport/knowledge-center/…
craigmichaelmartin

이 답변은 정말 도움이되었습니다. 감사!
Waleed93

50

람다가 프록시로 사용되는 경우 응답 형식은

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

참고 : 본문은 문자열이어야합니다.


"response"가 객체의 이름 인 경우 JSON.stringify (response) 사용은 작동하지 않습니다. 이렇게 두는 것이 저에게 효과적이었습니다. callback(null,response);
Neo

4
@Neo 응답 개체를 문자열화할 필요가 없습니다. 응답 개체의 본문 키 내부 데이터를
문자열

호기심에서-몸을 끈으로 묶어야하는 이유는 무엇입니까? 이것은 내가 작업 봤는데 뭔가에 내 문제, 그리고 그 왼쪽 나를 혼란 - 감사합니다
앤디 맥 컬러

2
이 중 statusCodeAPI Gateway의 호출이 성공하는 데만 필요합니다.
Trenton

몸을 끈으로 묶는 것이 나를 위해 일했습니다. 감사합니다 +1
Kimutai

26

예, 저는 이것이 실제로 적절한 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'}))

우리가 사실로 액세스 제어 - 허용 - 자격 증명 값을 사용하는 경우 이제, 우리는 '액세스 제어 - 허용 - 원산지' '*'와 같은 값을 유지하지 못할
Santhosh Nagulanchi

1
Origin : headers : { "Access-Control-Allow-Origin": "<< Single Domain >>", "Access-Control-Allow-Credentials": true // 쿠키에 필요합니다. HTTPS}
Santhosh Nagulanchi

6

로부터 AWS의 문서

Node.js의 Lambda 함수에서 성공적인 응답을 반환하려면 callback (null, { "statusCode": 200, "body": "results"})를 호출합니다. 예외를 발생 시키려면 callback (new Error ( 'internal server error'))를 호출하십시오. 클라이언트 측 오류 (예 : 필수 매개 변수가 누락 된 경우)의 경우 callback (null, { "statusCode": 400, "body": "Missing parameters of ..."})을 호출하여 오류를 발생시키지 않고 오류를 반환 할 수 있습니다. 예외.


5

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
    }

가 참고 body그냥 비어있을 수 설정 될 필요가 없습니다 :

        'body': ''

3

매우 특별한 경우, 헤더를 직접 전달하면 다음과 같은 헤더가있을 가능성이 있습니다.

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

그러나 Amazon에는 다음이 필요합니다.

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


3

응답이 유효 해 보일 때 어려움을 겪는 다른 사람을 위해. 작동하지 않습니다.

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

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

위의 제안을 모두 시도했지만 body가치가없는 동안 작동 하지 않습니다.String

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

3

.net 코어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;

람다의 응답은 다음과 같습니다.

{"statusCode":200,"headers":{"Content-Type":"application/json"},"multiValueHeaders":null,"body":"{\"msg\":\"Welcome to Belarus! :)\"}","isBase64Encoded":false}

API 게이트웨이의 응답은 다음과 같습니다.

{"msg":"Welcome to Belarus! :)"}

1
OMG, 정말 고마워요. 응답에서 헤더를 얻는 방법을 알아 내려고 몇 시간 후에 저를 구했습니다. 일반 JSON을 시도했지만 작동하지 않았습니다. 키 값 쌍을 시도했지만 작동하지 않았습니다. 사전은 갈 길이었습니다! 감사합니다!
Misha

1

CloudFormation AWS :: Serverless :: Api 리소스에서 실수로 ServerlessExpressLambdaFunctionName 변수를 제거했기 때문에이 오류가 발생했습니다. 여기의 컨텍스트는 https://github.com/awslabs/aws-serverless-express "AWS Lambda 및 Amazon API Gateway를 기반으로 기존 Node.js 애플리케이션 프레임 워크를 사용하여 서버리스 애플리케이션 및 REST API 실행"입니다.


0

위의 내용이 누구에게도 작동하지 않는 경우 응답 변수를 올바르게 설정 했음에도 불구하고이 오류가 발생했습니다.

내 기능에서 RDS 데이터베이스를 호출했습니다. 문제의 원인은 해당 데이터베이스의 보안 그룹 규칙 (인바운드)이었습니다.

API에 액세스 할 수있는 IP 주소를 제한하고 싶을 것입니다.하지만 변경 사항이 수정되었는지 테스트하기 위해 신속하게 / 더러워지고 싶다면 모든 것을 수락하도록 설정할 수 있습니다 (또한 모든 포트를 허용하도록 포트의 범위를 지정했지만이 예제에서는 수행하지 않았습니다.)

여기에 이미지 설명 입력


0

"잘못된 Lambda 프록시 응답"오류의 일반적인 원인은 키 / 값 쌍이 headers아니기 때문 {String: String, ...}입니다.

이후 set-cookie헤더와 배수에 표시 할 수있는 바와 같이, 이들은 http.request.callback.response 표현되는 set-cookie키가 갖는 ArrayStrings (A)의 값을 대신 단일String . 이것은 개발자에게는 작동하지만 AWS API Gateway는이를 이해하지 못하고 "잘못된 Lambda 프록시 응답"오류를 발생시킵니다.

내 해결책은 다음과 같이하는 것입니다.

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

여기에 또 다른 접근 방식이 있습니다. API 게이트웨이 통합 요청 및 응답에서 매핑 템플릿을 구성합니다. IntegrationRequest-> MappingTemplate-> "정의 된 템플릿이없는 경우"선택-> content-type에 대해 application / json을 입력합니다. 그러면 명시 적으로 json을 보낼 필요가 없습니다. 클라이언트에서받는 응답조차도 일반 문자열이 될 수 있습니다.


0

함수 응답의 형식이이 오류의 원인입니다. API Gateway가 Lambda 함수의 응답을 처리하려면 응답이 다음 형식의 JSON이어야합니다.

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

다음은 응답 형식이 올바른 Node.js의 예제 함수입니다.

exports.handler = (이벤트, 컨텍스트, 콜백) => {

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

};

참조 : https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/


0

파이썬 3.7

전에

{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": response.json()
}

{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": str(response.json()) //body must be of string type
}

0

AWS를 처음 사용하고 URL이 작동하기를 원하는 경우,

Lambda 함수에 대한 트리거를 생성하지 않은 경우 Lambda Functions 앱의 함수로 이동하여 API 게이트웨이를 선택하는 트리거를 생성합니다.

API Gateway 앱으로 이동-> 특정 Lambda의 API 게이트웨이 선택 (메소드 실행)-> 통합 요청 클릭-> "Lambda 프록시 통합 사용" (확인란)을 선택 취소 합니다.

그런 다음 " <-Method Execution "을 클릭하고 Test Client 섹션을 클릭합니다. 옵션을 제공하고 테스트 버튼을 클릭합니다. 성공 응답이 표시되어야합니다.

여전히 성공 응답을받을 수없는 경우 올바른 버전의 별칭을 생성합니다 (Lambda 함수에 여러 버전이있는 경우).

로그에서 URL을 선택하고 POST / GET 도구 (Postman)를 사용하고 AWS 서명으로 인증을 선택합니다. AWS 리전 및 서비스 이름을 lambda로 사용하여 우편 배달부 요청에 인증 키 (AccessKey 및 SecretKey)를 제공합니다.

추신 : 이것은 초보자에게만 도움이 될 수 있으며 다른 사람들과 관련이 없을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.