API Gateway의 Lambda 프록시 통합 - Amazon API Gateway

API Gateway의 Lambda 프록시 통합

다음 섹션에서는 Lambda 프록시 통합을 사용하는 방법을 보여줍니다.

API Gateway Lambda 프록시 통합 이해

Amazon API Gateway의 Lambda 프록시 통합은 단일 API 메서드의 설정을 통해 API를 구축하기 위한 간단하고 강력하며 민첩한 메커니즘입니다. Lambda 프록시 통합을 사용하면 클라이언트가 백엔드에서 단일 Lambda 함수를 호출할 수 있습니다. 이 함수는 다른 Lambda 함수를 호출하는 등 다른 AWS 서비스의 많은 리소스 또는 기능에 액세스합니다.

Lambda 프록시 통합에서 클라이언트가 API 요청을 제출하면 API Gateway는 통합된 Lambda 함수로 이벤트 객체를 전달합니다. 단, 요청 파라미터의 순서는 유지되지 않습니다. 요청 데이터에는 요청 헤더, 쿼리 문자열 파라미터, URL 경로 변수, 페이로드 및 API 구성 데이터가 포함되어 있습니다. 구성 데이터에는 현재 배포 단계 이름, 단계 변수, 사용자 ID 또는 권한 부여 컨텍스트(있는 경우)가 포함될 수 있습니다. 백엔드 Lambda 함수는 수신되는 요청 데이터를 구문 분석하여 반환하는 응답을 결정합니다. API Gateway에서 Lambda 출력을 클라이언트에 대한 API 응답으로 전달하려면 Lambda 함수에서 이 형식으로 결과를 반환해야 합니다.

API Gateway는 Lambda 프록시 통합을 위해 클라이언트와 백엔드 Lambda 함수 사이에 개입하지 않기 때문에 클라이언트와 통합된 Lambda 함수는 API의 기존 통합 설정을 깨지 않고 서로의 변화에 맞게 조정할 수 있습니다. 이렇게 하려면 클라이언트가 백엔드 Lambda 함수에 의해 제정된 애플리케이션 프로토콜을 따라야 합니다.

모든 API 메서드에 대해 Lambda 프록시 통합을 설정할 수 있습니다. 그러나 Lambda 프록시 통합은 일반 프록시 리소스가 포함된 API 메서드에 대해 구성될 때 더 강력합니다. 일반 프록시 리소스는 {proxy+}의 특수 템플릿 경로 변수, catch-all ANY 메서드 자리 표시자 또는 둘 다로 표시될 수 있습니다. 클라이언트는 수신되는 요청의 백엔드 Lambda 함수에 대한 입력을 요청 파라미터 또는 해당 페이로드로 전달할 수 있습니다. 요청 파라미터에는 헤더, URL 경로 변수, 쿼리 문자열 파라미터 및 해당 페이로드가 포함되어 있습니다. 통합된 Lambda 함수는 필요한 입력이 누락된 경우 요청을 처리하고 의미 있는 오류 메시지로 클라이언트에 응답하기 전에 모든 입력 소스를 확인합니다.

일반 HTTP 메서드 ANY 및 일반 리소스 {proxy+}와 통합된 API 메서드를 호출할 때 클라이언트는 ANY 대신 특정 HTTP 메서드를 사용하여 요청을 제출합니다. 또한 클라이언트는 {proxy+} 대신 특정 URL 경로를 지정하고 필수 헤더, 쿼리 문자열 파라미터 또는 해당 페이로드를 포함합니다.

다음 목록에는 Lambda 프록시 통합을 통해 다양한 API 메서드의 런타임 동작이 요약되어 있습니다.

  • ANY /{proxy+}: 클라이언트는 특정 HTTP 메서드를 선택하고 특정 리소스 경로 계층을 설정해야 하며 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.

  • ANY /res: 클라이언트는 특정 HTTP 메서드를 선택해야 하고 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.

  • GET|POST|PUT|... /{proxy+}: 클라이언트는 특정 리소스 경로 계층, 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 데이터를 통합된 Lambda 함수에 대한 입력으로 전달할 수 있습니다.

  • GET|POST|PUT|... /res/{path}/...: 클라이언트는 특정 경로 세그먼트({path} 변수의 경우)를 선택해야 하고 요청 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 설정하여 입력 데이터를 통합된 Lambda 함수에 전달할 수 있습니다.

  • GET|POST|PUT|... /res: 클라이언트는 요청 헤더, 쿼리 문자열 파라미터 및 해당 페이로드를 선택하여 입력 데이터를 통합된 Lambda 함수에 전달할 수 있습니다.

프록시 리소스 {proxy+} 및 사용자 지정 리소스 {custom} 모두 템플릿 경로 변수로 표현됩니다. 그러나 {proxy+}는 경로 계층을 따라 모든 리소스를 참조할 수 있지만 {custom}은 특정 경로 세그먼트만 참조합니다. 예를 들어 식품 매장은 부서 이름, 생산 카테고리 및 제품 유형별로 온라인 제품 재고를 구성할 수 있습니다. 식품 매장의 웹 사이트는 사용자 지정 리소스의 템플릿 경로 변수인 /{department}/{produce-category}/{product-type}을 사용하여 사용 가능한 제품을 나타낼 수 있습니다. 예를 들어 사과는 /produce/fruit/apple로, 당근은 /produce/vegetables/carrot으로 표현됩니다. 또한 /{proxy+}를 사용하여 온라인 매장에서 쇼핑하는 동안 고객이 검색할 수 있는 부서, 생산 카테고리 또는 제품 유형을 나타낼 수 있습니다. 예를 들어 /{proxy+}는 다음 항목 중 하나를 참조할 수 있습니다.

  • /produce

  • /produce/fruit

  • /produce/vegetables/carrot

고객이 사용 가능한 제품, 제품 카테고리 및 관련 매장 부서를 검색할 수 있게 하려면 읽기 전용 권한으로 GET /{proxy+}의 단일 메서드를 공개할 수 있습니다. 마찬가지로 감독자가 produce 부서의 재고를 업데이트할 수 있게 하려면 읽기/쓰기 권한으로 PUT /produce/{proxy+}의 또 다른 단일 메서드를 설정할 수 있습니다. 점원이 야채의 총 누계를 업데이트할 수 있게 하려면 읽기/쓰기 권한으로 POST /produce/vegetables/{proxy+} 메서드를 설정할 수 있습니다. 매장 관리자가 사용 가능한 제품에 대해 가능한 조치를 수행할 수 있게 하려면 온라인 매장 개발자는 읽기/쓰기 권한으로 ANY /{proxy+} 메서드를 공개할 수 있습니다. 어떤 경우에도 런타임 시 고객 또는 직원은 선택한 부서에서 지정된 유형의 특정 제품, 선택한 부서의 특정 생산 카테고리 또는 특정 부서를 선택해야 합니다.

API Gateway 프록시 통합 설정에 대한 자세한 내용은 프록시 리소스를 사용하여 프록시 통합 설정를 참조하세요.

프록시 통합을 위해서는 클라이언트가 백엔드 요구 사항에 대해 보다 자세한 지식을 갖추고 있어야 합니다. 따라서 최적의 앱 성능과 사용자 경험을 보장하려면 백엔드 개발자는 클라이언트 개발자에게 백엔드 요구 사항을 명확하게 전달하고 요구 사항이 충족되지 않으면 강력한 오류 피드백 메커니즘을 제공해야 합니다.

다중 값 헤더 및 쿼리 문자열 파라미터에 대한 지원

API Gateway는 이제 동일한 이름을 지닌 복수의 헤더 및 쿼리 문자열 파라미터를 지원합니다. 다중 값 헤더와 단일 값 헤더 및 파라미터는 동일한 요청 및 응답에서 결합될 수 있습니다. 자세한 내용은 프록시 통합에 대한 Lambda 함수의 입력 형식프록시 통합에 대한 Lambda 함수의 출력 형식 단원을 참조하세요.

프록시 통합에 대한 Lambda 함수의 입력 형식

Lambda 프록시 통합을 사용할 경우 API Gateway에서 전체 클라이언트 요청을 백엔드 Lambda 함수의 입력 event 파라미터에 매핑합니다. 다음 예제에서는 API Gateway가 Lambda 프록시 통합으로 보내는 이벤트의 구조를 보여줍니다.

{ "resource": "/my/path", "path": "/my/path", "httpMethod": "GET", "headers": { "header1": "value1", "header2": "value1,value2" }, "multiValueHeaders": { "header1": [ "value1" ], "header2": [ "value1", "value2" ] }, "queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" }, "multiValueQueryStringParameters": { "parameter1": [ "value1", "value2" ], "parameter2": [ "value" ] }, "requestContext": { "accountId": "123456789012", "apiId": "id", "authorizer": { "claims": null, "scopes": null }, "domainName": "id.execute-api.us-east-1.amazonaws.com", "domainPrefix": "id", "extendedRequestId": "request-id", "httpMethod": "GET", "identity": { "accessKey": null, "accountId": null, "caller": null, "cognitoAuthenticationProvider": null, "cognitoAuthenticationType": null, "cognitoIdentityId": null, "cognitoIdentityPoolId": null, "principalOrgId": null, "sourceIp": "IP", "user": null, "userAgent": "user-agent", "userArn": null, "clientCert": { "clientCertPem": "CERT_CONTENT", "subjectDN": "www.example.com", "issuerDN": "Example issuer", "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", "validity": { "notBefore": "May 28 12:30:02 2019 GMT", "notAfter": "Aug 5 09:36:04 2021 GMT" } } }, "path": "/my/path", "protocol": "HTTP/1.1", "requestId": "id=", "requestTime": "04/Mar/2020:19:15:17 +0000", "requestTimeEpoch": 1583349317135, "resourceId": null, "resourcePath": "/my/path", "stage": "$default" }, "pathParameters": null, "stageVariables": null, "body": "Hello from Lambda!", "isBase64Encoded": false }
참고

입력에서:

  • headers 키에는 단일 값 헤더만 있습니다.

  • multiValueHeaders 키에는 다중 값 헤더와 단일 값 헤더가 있을 수 있습니다.

  • headersmultiValueHeaders 모두에 대해 값을 지정한 경우, API Gateway는 이들 헤더를 단일 목록으로 병합합니다. 동일한 키-값 페어가 양쪽 모두에 지정된 경우, multiValueHeaders의 값만이 병합된 목록에 표시됩니다.

백엔드 Lambda 함수에 대한 입력에서 requestContext 객체는 키-값 페어의 맵입니다. 각 페어에서 키는 $context 변수 속성의 이름이고, 값은 그 속성의 값입니다. API Gateway는 새 키를 맵에 추가할 수 있습니다.

활성화된 기능에 따라 requestContext 맵은 API마다 다를 수 있습니다. 예를 들어 앞의 예제에서는 권한 부여 유형이 지정되지 않았으므로 $context.authorizer.* 또는 $context.identity.* 속성이 없습니다. 권한 부여 유형이 지정된 경우에는 다음과 같이 API Gateway가 requestContext.identity 객체의 통합 엔드포인트에 권한이 부여된 사용자 정보를 전달합니다.

  • 권한 부여 유형이 AWS_IAM인 경우, 권한 부여된 사용자 정보에 $context.identity.* 속성이 포함됩니다.

  • 권한 부여 유형이 COGNITO_USER_POOLS(Amazon Cognito 권한 부여자)인 경우, 권한 부여된 사용자 정보에 $context.identity.cognito*$context.authorizer.claims.* 속성이 포함됩니다.

  • 권한 부여 유형이 CUSTOM(Lambda 권한 부여자)인 경우, 권한 부여된 사용자 정보에 $context.authorizer.principalId 및 기타 적용되는 $context.authorizer.* 속성이 포함됩니다.

프록시 통합에 대한 Lambda 함수의 출력 형식

Lambda 프록시 통합을 사용할 경우 API Gateway에서는 백엔드 Lambda 함수에 다음 JSON 형식에 따라 출력을 반환하도록 요구합니다.

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

출력에서:

  • 출력에서 추가 응답 헤더가 반환되지 않을 경우 headersmultiValueHeaders 키가 비지정 상태일 수 있습니다.

  • headers 키에는 단일 값 헤더만 있습니다.

  • multiValueHeaders 키에는 다중 값 헤더와 단일 값 헤더가 있을 수 있습니다. multiValueHeaders 키를 사용하여 모든 단일 값 헤더를 포함하는 모든 추가 헤더를 지정할 수 있습니다.

  • headersmultiValueHeaders 모두에 대해 값을 지정한 경우, API Gateway는 이들 헤더를 단일 목록으로 병합합니다. 동일한 키-값 페어가 양쪽 모두에 지정된 경우, multiValueHeaders의 값만이 병합된 목록에 표시됩니다.

Lambda 프록시 통합에 대해 CORS를 활성화하려면 출력 headersAccess-Control-Allow-Origin:domain-name을 추가해야 합니다. domain-name은 모든 도메인 이름에 대해 *일 수 있습니다. 출력 body는 프런트엔드에 메서드 응답 페이로드로 마샬링됩니다. body가 이진 BLOB인 경우 isBase64Encodedtrue으로 설정하고, 이진 미디어 유형*/*로 구성하여 Base64로 인코딩된 문자열로 인코딩할 수 있습니다. 그렇지 않은 경우 false로 설정하거나 지정되지 않은 상태로 둘 수 있습니다.

참고

이진 지원 활성화에 대한 자세한 내용은 API Gateway 콘솔을 사용하여 이진 지원 활성화 단원을 참조하세요. Lambda 함수의 예는 API Gateway의 Lambda 프록시 통합에서 이진 미디어 반환를 참조하세요.

함수 출력의 형식이 다른 경우 API Gateway에서는 502 Bad Gateway 오류 응답을 반환합니다.

Node.js에서 Lambda 함수의 응답을 반환하려면 다음과 같은 명령어를 사용할 수 있습니다.

  • 성공 결과를 반환하려면 callback(null, {"statusCode": 200, "body": "results"})을 호출합니다.

  • 예외를 발생하려면 callback(new Error('internal server error'))를 호출합니다.

  • 클라이언트 측 오류의 경우(예: 필요한 파라미터가 없는 경우) callback(null, {"statusCode": 400, "body": "Missing parameters of ..."})를 호출하여 예외를 발생하지 않고 오류를 반환할 수 있습니다.

Node.js의 Lambda async 함수에서 이와 동일한 구문은 다음과 같습니다.

  • 성공 결과를 반환하려면 return {"statusCode": 200, "body": "results"}을 호출합니다.

  • 예외를 발생하려면 throw new Error("internal server error")를 호출합니다.

  • 클라이언트 측 오류의 경우(예: 필요한 파라미터가 없는 경우) return {"statusCode": 400, "body": "Missing parameters of ..."}를 호출하여 예외를 발생하지 않고 오류를 반환할 수 있습니다.