AWS lambda API 게이트웨이 오류 "형식이 잘못된 Lambda 프록시 응답"
AWS lambda로 hello world 예제를 설정하고 api 게이트웨이를 통해 서비스하려고 합니다.apatway를 설정하고 Blank Function 옵션을 선택하는 "Create a Lambda Function"을 클릭했습니다.AWS 게이트웨이 시작 가이드에 있는 람다 함수를 추가했습니다.
exports.handler = function(event, context, callback) {
callback(null, {"Hello":"World"}); // SUCCESS with message
};
응답 는 GET 502 이 입니다 을 입니다 을 이 는 { "message": "Internal server error" }
에 "오류로 : 의 람다 응답이라고 표시됩니다 그리고 로그에는 "구성 오류로 인한 실행 실패: 잘못된 형식의 Lambda proxy response"라고 기록되어 있습니다.
보통 볼 때는.Malformed Lambda proxy response
은 당신의 합니다. , 의 로부터의 의 이 가 합니다 하는 을 과 하지 은 합니다 을 하지 가 과 은 하는
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
Lambda 프록시 통합을 사용하지 않는 경우 API Gateway 콘솔에 로그인하고 Lambda 프록시 통합 확인란의 선택을 취소할 수 있습니다.
또한 간헐적으로 발생하는 경우Malformed Lambda proxy response
Lambda에 할 수 , Lambda Lambda Lambda 에 을 를 해야 할 에 이 되었다는 해야 를 에 에
람다를 프록시로 사용하는 경우 응답 형식은 다음과 같습니다.
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}
참고: 본체는 끈으로 묶어야 합니다.
네, 제 생각에 이것은 당신이 거기에 제대로 된 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'}))
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': ''
잘못된 핸들러 코드로 인해 문제가 발생했습니다.
exports.handler = (event, context) => {
return {
isBase64Encoded: false,
body: JSON.stringify({ foo: "bar" }),
headers: {
'Access-Control-Allow-Origin': '*',
},
statusCode: 200,
};
}
다소 혼란스러운 API Gateway 응답 로그를 조사하여 힌트를 얻었습니다.
> Endpoint response body before transformations: null
이 문제를 해결하는 방법은
- 를 .
async
키워드(비동기 함수는 암묵적으로 약속을 반환함):
exports.handler = async (event, context) => {
return {
isBase64Encoded: false,
body: JSON.stringify({ foo: "bar" }),
headers: {
'Access-Control-Allow-Origin': '*',
},
statusCode: 200,
};
}
- 약속을 반환합니다.
exports.handler = (event, context) => {
return new Promise((resolve) => resolve({
isBase64Encoded: false,
body: JSON.stringify({ foo: "bar" }),
headers: {
'Access-Control-Allow-Origin': '*',
},
statusCode: 200,
}));
}
- 콜백 사용:
exports.handler = (event, context, callback) => {
callback({
isBase64Encoded: false,
body: JSON.stringify({ foo: "bar" }),
headers: {
'Access-Control-Allow-Origin': '*',
},
statusCode: 200,
});
}
내 핸들러는 이전에 신고되었습니다.async
전혀 쓰지 않고await
, 그래서 제거했습니다.async
키워드는 Lambda가 비동기/대기/약속 또는 콜백 리턴 방법을 사용할 것을 예상하지 못한 채 코드의 복잡성을 줄여줍니다.
Node.js의 람다 함수에서 성공적인 응답을 반환하려면 콜백(null, {"statusCode": 200, "body": "results"})을 호출합니다.예외를 삭제하려면 콜백(new Error('내부 서버 오류')을 호출합니다.클라이언트 측 오류(예: 필수 매개 변수가 누락된 경우 콜백(null, {"statusCode": 400, "body": "missing parameter of ...")을 호출할 수 있습니다."}) 예외를 두지 않고 오류를 반환합니다.
.net core와 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! :)"}
의 을 해 이 이 의 해 body
이다가 .String
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
success: true
}),
isBase64Encoded: false
};
응답이 유효한 것처럼 보일 때 어려움을 겪는 모든 사용자에게 해당합니다.작동하지 않습니다.
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'
})
또한 응답 개체에 추가 키가 있을 수 없는 것으로 보입니다.
아주 특별한 경우로, 헤더를 직접 전달하면 다음과 같은 헤더가 나올 가능성이 있습니다.
"set-cookie": [ "........" ]
하지만 아마존은 이것을 필요로 합니다.
"set-cookie": "[ \\"........\\" ]"
바둑은 AWS Lambda를 사용하는 경우는events.APIGatewayProxyResponse
.
func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
return events.APIGatewayProxyResponse{
IsBase64Encoded: false,
StatusCode: 200,
Headers: headers,
Body: body,
}, nil
}
은 의 에 이 에 JSON
,식,만)STRING
형식은 Lambda 프록시를 API Gateway와 통합할 수 있습니다.
그래서 당신의 오래된 반응체를 싸세요.JSON.stringify()
.
CloudFormation AWS::Serverless::에서 ServerlessExpressLambdaFunctionName 변수를 실수로 제거하여 이 오류가 발생했습니다.API 리소스.여기서의 맥락은 "AWS Lambda 및 Amazon API Gateway 위에 기존 Node.js 응용 프로그램 프레임워크를 사용하여 서버리스 응용 프로그램 및 REST API 실행"입니다.
위의 내용이 누구에게도 통하지 않을 경우, 응답 변수를 올바르게 설정했음에도 불구하고 이 오류를 범했습니다.
저는 제 기능에 있는 RDS 데이터베이스에 전화를 걸고 있었습니다.문제의 원인은 해당 데이터베이스의 보안 그룹 규칙(인바운드)인 것으로 나타났습니다.
API에 액세스할 수 있는 IP 주소를 제한해야 할 수도 있지만, 변경 사항이 수정되면 테스트를 위해 빨리 작동하거나 더럽게 작동하도록 하려면 모든 포트를 허용하도록 설정할 수 있습니다(포트의 범위를 모든 포트를 허용하도록 설정할 수도 있지만, 이 예에서는 이 작업을 수행하지 않았습니다.
response"은 "Malformed Lambda proxy response"입니다.headers
가 아닌{String: String, ...}
키/값 쌍.
set-cookie
.request.callback.response의 http.request.callback.response의 http.request.callback.response의 http.request.callback.response의 http.response의set-cookie
키는 싱글이 아닌 가치가 있습니다.이것은 개발자들에게는 효과가 있지만 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 스프레드 오퍼레이터입니다.
다른 방법이 있습니다.API 게이트웨이 통합 요청 및 응답에서 매핑 템플릿을 구성합니다.IntegrationRequest -> MappingTemplate -> "Template가 정의되어 있지 않을 때" -> application/json을 컨텐츠 유형으로 선택합니다.그렇다면 json을 명시적으로 보낼 필요는 없습니다.고객에게 받는 응답도 간단한 문자열이 될 수 있습니다.
파이썬 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
}
만약 당신이 AWS에 처음이고 당신의 URL이 작동하기를 원한다면,
Lambda Function에 대한 트리거를 생성하지 않은 경우 Lambda Functions app에서 해당 기능으로 이동하고 API Gateway를 선택하여 트리거를 생성합니다.
API Gateway App으로 이동 -> 특정 Lambda의 API Gateway 선택(Method 실행) -> INTEGATION 요청 클릭 -> "Lambda Proxy integration 사용" 선택 취소(체크박스)
그리고 "<-Method Execution"을 클릭한 후 Test Client 섹션을 클릭합니다.옵션을 제공하고 테스트 버튼을 클릭합니다.성공적인 반응을 볼 수 있을 겁니다.
그래도 성공적인 응답을 얻을 수 없으면 올바른 버전에 대한 별칭을 만듭니다(Lambda Function에 여러 버전이 있는 경우).
로그에서 URL을 선택한 후 POST/GET Tool(포스트맨)을 사용하여 인증을 AWS Signature - AWS Region & Service Name에서 인증키(AccessKey & SecretKey)를 lambda로 제공합니다.
추신: 이것은 초보자들에게만 도움이 될 수도 있고 다른 사람들과는 무관할 수도 있습니다.
함수 응답 형식이 이 오류의 원인입니다.API Gateway가 Lambda 함수의 응답을 처리하려면 다음 형식의 응답이 JSON이어야 합니다.
{ "isBase64Encoded": true|false, "statusCode": httpStatusCode, "헤더": { "headerName":"headerValue", ... }, "body": "... }
Node.js의 응답 형식이 정확한 함수 예는 다음과 같습니다.
exports.fault = (이벤트, 컨텍스트, 콜백) => {
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);
};
참조:Lambda proxy 통합으로 API Gateway REST API의 HTTP 502 오류를 해결하려면 어떻게 해야 합니까?
언급URL : https://stackoverflow.com/questions/43708017/aws-lambda-api-gateway-error-malformed-lambda-proxy-response
'programing' 카테고리의 다른 글
배열의 길이를 확인하려면 어떻게 해야 합니까? (0) | 2023.09.06 |
---|---|
타임스탬프를 MySQL 테이블에 삽입하는 방법? (0) | 2023.09.06 |
python의 bining 데이터에 skipy/numpy가 포함된 (0) | 2023.09.06 |
mysql_real_escape_string VS 슬래시 추가 (0) | 2023.09.06 |
jQuery $(.class").click(); - 다중 요소, 이벤트 한 번 클릭 (0) | 2023.09.01 |