자습서: Lambda 비 프록시 통합을 통해 REST API 생성
이 연습에서는 API Gateway 콘솔을 사용하여 클라이언트가 Lambda 비 프록시 통합(사용자 지정 통합이라고도 함)을 통해 Lambda 함수를 호출할 수 있도록 하는 API를 빌드합니다. AWS Lambda 및 Lambda 함수에 대한 자세한 내용은 AWS Lambda 개발자 안내서를 참조하세요.
원활한 학습을 위해 최소 API 설정으로 간단한 Lambda 함수를 선택하여 Lambda 사용자 지정 통합을 통해 API Gateway API를 구축하는 단계를 안내합니다. 필요한 경우 일부 로직에 대해 설명합니다. Lambda 사용자 지정 통합에 대한 자세한 예제는 튜토리얼: 두 개의 AWS 서비스 통합과 하나의 Lambda 비프록시 통합으로 REST API 생성을 참조하십시오.
API를 생성하기 전에 다음에 설명한 대로 AWS Lambda에서 Lambda 함수를 생성하여 Lambda 백엔드를 설정합니다.
Lambda 비 프록시 통합을 위한 Lambda 함수 만들기
참고
Lambda 함수를 생성하면 AWS 계정에 요금이 발생할 수 있습니다.
이 단계에서는, "Hello, World!"와 같은 Lambda 사용자 지정 통합에 대한 Lambda 함수를 생성해 봅니다. 이 연습에서는 GetStartedLambdaIntegration
이라는 함수가 사용됩니다.
이 GetStartedLambdaIntegration
Lambda 함수의 구현은 다음과 같습니다.
Lambda 사용자 지정 통합의 경우 API Gateway에서 입력을 통합 요청 본문으로 클라이언트의 Lambda 함수에 전달합니다. Lambda 함수 핸들러의 event
객체는 입력입니다.
Lambda 함수는 간단합니다. event
, name
, city
, time
속성에 대한 입력 day
객체를 구문 분석합니다. 그런 다음 인사말을 {"message":greeting}
의 JSON 객체로 호출자에게 반환합니다. 메시지는 "Good
[morning|afternoon|day], [
패턴입니다. Lambda 함수에 대한 입력이 다음 JSON 객체라고 가정합니다.name
|you] in
[city
|World]. Happy
day
!"
{ "city": "...", "time": "...", "day": "...", "name" : "..." }
자세한 내용은 AWS Lambda 개발자 안내서를 참조하십시오.
또한 이 함수는 console.log(...)
를 호출하여 실행을 Amazon CloudWatch에 기록합니다. 이는 함수를 디버깅할 때 호출 트레이스에 유용합니다. GetStartedLambdaIntegration
함수가 호출을 기록하도록 허용하려면 Lambda 함수가 CloudWatch 스트림을 생성하고 로그 항목을 스트림에 추가할 수 있도록 적절한 정책을 사용하여 IAM 역할을 설정합니다. Lambda 콘솔은 필요한 IAM 역할과 정책을 생성하도록 안내합니다.
API Gateway 콘솔을 사용하지 않고 API를 설정할 경우(예: OpenAPI 파일에서 API를 가져오는 경우
Lambda 프록시 통합에 대한 Lambda 함수인 GetStartedLambdaProxyIntegration
과 달리 Lambda 사용자 지정 통합에 대한 GetStartedLambdaIntegration
Lambda 함수는 API Gateway API 통합 요청 본문에서 입력만 가져옵니다. 함수는 JSON 객체, 문자열, 숫자, 부울 또는 심지어 이진 BLOB의 출력을 반환할 수 있습니다. 반대로 Lambda 프록시 통합에 대한 Lambda 함수는 모든 요청 데이터에서 입력을 가져올 수 있지만 특정 JSON 객체의 출력을 반환해야 합니다. API Gateway에서 클라이언트 요청을 백엔드로 전달하기 전에 필요한 API 요청 파라미터를 통합 요청 본문에 매핑하는 경우 Lambda 사용자 지정 통합에 대한 GetStartedLambdaIntegration
함수는 API 요청 파라미터를 입력으로 가질 수 있습니다. 이를 위해 API 개발자는 API를 생성할 때 매핑 템플릿을 생성하여 API 메서드에서 구성해야 합니다.
이제 GetStartedLambdaIntegration
Lambda 함수를 생성합니다.
Lambda 사용자 지정 통합을 위한 GetStartedLambdaIntegration
Lambda 함수를 생성하려면
AWS Lambdahttps://console.aws.amazon.com/lambda/에서
콘솔을 엽니다. -
다음 중 하나를 수행하십시오.
-
시작 페이지가 나타나면 지금 시작을 선택한 다음 함수 만들기를 선택합니다.
-
Lambda > 함수(Lambda > Functions) 목록 페이지가 나타나면 함수 만들기(Create function)를 선택합니다.
-
-
새로 작성을 선택합니다.
-
새로 작성 창에서 다음과 같이 합니다.
-
이름(Name)에 Lambda 함수 이름으로
GetStartedLambdaIntegration
을 입력합니다. -
런타임에서 지원되는 최신 Node.js 또는 Python 런타임을 선택합니다.
아키텍처의 경우 기본 설정을 유지합니다.
-
권한(Permissions)에서 기본 실행 역할 변경(Change default execution role)을 확장합니다. 실행 역할 드롭다운 목록에서 AWS 정책 템플릿에서 새 역할 생성을 선택합니다.
-
역할 이름에 역할의 이름을 입력합니다(예:
GetStartedLambdaIntegrationRole
). -
정책 템플릿에서 단순 마이크로서비스 권한을 선택합니다.
-
함수 생성을 선택합니다.
-
-
함수 구성 창의 Function code(함수 코드)에서, 다음 필드들을 설정하십시오.
-
이 섹션의 시작 부분에 나열된 Lambda 함수 코드를 복사하여 인라인 코드 편집기에 붙여 넣습니다.
-
이 섹션의 다른 필드를 모두 기본값으로 그대로 둡니다.
-
[Deploy]를 선택합니다.
-
-
새로 생성된 함수를 테스트하려면 테스트 탭을 선택합니다.
-
이벤트 이름에
HelloWorldTest
를 입력합니다. 이벤트 JSON에서 기본 코드를 다음과 같이 바꾸십시오.
{ "name": "Jonny", "city": "Seattle", "time": "morning", "day": "Wednesday" }
-
테스트를 선택하여 함수를 호출합니다. 실행 결과: 성공 섹션이 표시됩니다. 세부 정보를 확장하면 다음 출력이 표시됩니다.
{ "greeting": "Good morning, Jonny of Seattle. Happy Wednesday!" }
출력은 CloudWatch Logs에도 기록됩니다.
-
측면 연습으로 IAM 콘솔을 사용하여 Lambda 함수 생성의 일부로 생성된 IAM 역할(GetStartedLambdaIntegrationRole
)을 볼 수 있습니다. 이 IAM 역할에는 두 개의 인라인 정책이 연결되어 있습니다. 하나는 Lambda 실행을 위해 가장 기본적인 권한을 규정합니다. 이 정책은 Lambda 함수가 생성된 리전에서 계정의 CloudWatch 리소스에 대한 CloudWatch CreateLogGroup
호출을 허용합니다. 또한 이 정책을 사용하면 CloudWatch 스트림을 생성하고 GetStartedLambdaIntegration
Lambda 함수에 대한 이벤트를 기록할 수 있습니다.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:
region
:account-id
:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:region
:account-id
:log-group:/aws/lambda/GetStartedLambdaIntegration:*" ] } ] }
다른 정책 문서는 이 예제에서 사용되지 않은 다른 AWS 서비스를 호출하는 데 적용됩니다. 지금은 건너뛸 수 있습니다.
IAM 역할에는 lambda.amazonaws.com
인 신뢰할 수 있는 엔터티가 연결되어 있습니다. 다음은 신뢰 관계입니다.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
이 신뢰 관계와 인라인 정책을 조합하면 Lambda 함수가 console.log()
함수를 호출하여 이벤트를 CloudWatch Logs에 기록할 수 있습니다.
Lambda 비 프록시 통합을 통해 API 생성
Lambda 함수(GetStartedLambdaIntegration
)가 생성 및 테스트되면 API Gateway API를 통해 함수를 공개할 준비가 된 것입니다. 설명을 위해 일반 HTTP 메서드를 사용하여 Lambda 함수를 공개합니다. 요청 본문, URL 경로 변수, 쿼리 문자열 및 헤더를 사용하여 클라이언트로부터 필수 입력 데이터를 수신합니다. API에 대한 API Gateway 요청 검사기를 설정하여 모든 필수 데이터가 올바르게 정의되고 지정되었는지 확인합니다. 백엔드 Lambda 함수에 따라 클라이언트가 제공한 요청 데이터를 유효한 형식으로 변환하도록 API Gateway에 대한 매핑 템플릿을 구성합니다.
Lambda 비 프록시 통합을 통해 API를 생성하려면
-
https://console.aws.amazon.com/apigateway
에서 API Gateway 콘솔에 로그인합니다. -
API Gateway를 처음 사용하는 경우, 서비스의 기능을 소개하는 페이지가 나타납니다. REST API에서 빌드를 선택합니다. 예제 API 생성 팝업이 나타나면 확인을 선택합니다.
API Gateway를 처음 사용하는 것이 아닌 경우 API 생성을 선택합니다. REST API에서 빌드를 선택합니다.
API 이름에서
LambdaNonProxyAPI
을 입력합니다.(선택 사항) 설명에 설명을 입력합니다.
API 엔드포인트 유형 설정을 지역으로 유지합니다.
API 생성(Create API)을 선택합니다.
API를 생성한 후에는 /{city} 리소스를 생성합니다. 이는 클라이언트에서 입력을 가져오는 경로 변수를 포함하는 리소스의 예입니다. 나중에 이 경로 변수를 매핑 템플릿을 사용하여 Lambda 함수 입력에 매핑합니다.
리소스를 생성하려면
리소스 생성을 선택합니다.
프록시 리소스는 꺼진 상태로 둡니다.
리소스 경로를
/
로 유지합니다.리소스 이름에
{city}
을 입력합니다.오리진 간 리소스 공유(CORS)를 꺼진 상태로 둡니다.
리소스 생성을 선택합니다.
/{city} 리소스를 생성한 후에는 ANY
메서드를 생성합니다. ANY
HTTP 동사는 클라이언트가 런타임에 제출하는 유효한 HTTP 메서드의 자리 표시자입니다. 이 예제에서는 Lambda 사용자 지정 통합뿐만 아니라 Lambda 프록시 통합에 사용할 수 있는 ANY
메서드를 보여줍니다.
ANY
메서드를 생성하려면
/{city} 리소스를 선택한 다음 메서드 생성을 선택합니다.
메서드 유형에서 ANY를 선택합니다.
통합 유형에서 Lambda 함수를 선택합니다.
Lambda 프록시 통합을 비활성화된 상태로 유지합니다.
Lambda 함수에서 Lambda 함수를 생성한 AWS 리전을 선택하고 함수 이름을 입력합니다.
메서드 요청 설정을 선택합니다.
이제 URL 경로 변수, 쿼리 문자열 파라미터 및 헤더에 대한 요청 유효성 검사기를 켜서 필요한 모든 데이터가 정의되었는지 확인합니다. 이 예시에서는
time
쿼리 문자열 파라미터와day
헤더를 생성합니다.요청 검사기에서 쿼리 문자열 파라미터 및 헤더 검사를 선택합니다.
URL 쿼리 문자열 파라미터를 선택하고 다음을 수행합니다.
쿼리 문자열 추가(Add query string)를 선택합니다.
이름에
time
을 입력합니다.필수를 끕니다.
캐싱을 꺼진 상태로 둡니다.
HTTP 요청 헤더를 선택하고 다음을 수행합니다.
헤더 추가(Add header)를 선택합니다.
이름에
day
을 입력합니다.필수를 끕니다.
캐싱을 꺼진 상태로 둡니다.
메서드 생성을 선택합니다.
요청 검사기를 활성화한 후에는 백엔드 Lambda 함수에 필요한 대로 수신된 요청을 JSON 페이로드로 변환하는 본문 매핑 템플릿을 추가하여 ANY
메서드에 대한 통합 요청을 구성합니다.
통합 요청을 구성하려면
통합 요청 탭의 통합 요청 설정에서 편집을 선택합니다.
요청 본문 패스스루에서 정의된 템플릿이 없는 경우(권장)를 선택합니다.
매핑 템플릿을 선택합니다.
매핑 템플릿 추가(Add mapping template)를 선택합니다.
콘텐츠 유형에
application/json
을 입력합니다.템플릿 본문에 다음 코드를 입력합니다.
#set($inputRoot = $input.path('$')) { "city": "$input.params('city')", "time": "$input.params('time')", "day": "$input.params('day')", "name": "$inputRoot.callerName" }
Save(저장)를 선택합니다.
API 메서드 호출 테스트
API Gateway 콘솔은 배포되기 전에 API 호출을 테스트할 수 있는 테스트 기능을 제공합니다. 콘솔의 테스트 기능을 사용하여 다음 요청을 제출하는 방식으로 API를 테스트합니다.
POST /Seattle?time=morning day:Wednesday { "callerName": "John" }
이 테스트 요청에서는 ANY
를 POST
로 설정하고 {city}
를 Seattle
로 설정하며 Wednesday
를 day
헤더 값으로 할당하고 "John"
을 callerName
값으로 할당합니다.
ANY
메서드를 테스트하는 방법
-
테스트 탭을 선택합니다. 탭을 표시하려면 오른쪽 화살표 버튼을 선택해야 할 수도 있습니다.
-
메서드 유형에서
POST
를 선택합니다. -
경로의 city에
Seattle
을 입력합니다. -
쿼리 문자열에
time=morning
를 입력합니다. -
헤더에
day:Wednesday
를 입력합니다. -
요청 본문에
{ "callerName": "John" }
을 입력합니다. -
테스트를 선택합니다.
반환된 응답 페이로드가 다음과 같은지 확인합니다.
{ "greeting": "Good morning, John of Seattle. Happy Wednesday!" }
로그를 보고 API Gateway에서 요청 및 응답을 처리하는 방식을 알아볼 수도 있습니다.
Execution log for request test-request Thu Aug 31 01:07:25 UTC 2017 : Starting execution for request: test-invoke-request Thu Aug 31 01:07:25 UTC 2017 : HTTP Method: POST, Resource Path: /Seattle Thu Aug 31 01:07:25 UTC 2017 : Method request path: {city=Seattle} Thu Aug 31 01:07:25 UTC 2017 : Method request query string: {time=morning} Thu Aug 31 01:07:25 UTC 2017 : Method request headers: {day=Wednesday} Thu Aug 31 01:07:25 UTC 2017 : Method request body before transformations: { "callerName": "John" } Thu Aug 31 01:07:25 UTC 2017 : Request validation succeeded for content type application/json Thu Aug 31 01:07:25 UTC 2017 : Endpoint request URI: https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************338c72, X-Amz-Date=20170831T010725Z, x-amzn-apigateway-api-id=beags1mnid, X-Amz-Source-Arn=arn:aws:execute-api:us-west-2:123456789012:beags1mnid/null/POST/{city}, Accept=application/json, User-Agent=AmazonAPIGateway_beags1mnid, X-Amz-Security-Token=FQoDYXdzELL//////////wEaDMHGzEdEOT/VvGhabiK3AzgKrJw+3zLqJZG4PhOq12K6W21+QotY2rrZyOzqhLoiuRg3CAYNQ2eqgL5D54+63ey9bIdtwHGoyBdq8ecWxJK/YUnT2Rau0L9HCG5p7FC05h3IvwlFfvcidQNXeYvsKJTLXI05/yEnY3ttIAnpNYLOezD9Es8rBfyruHfJfOqextKlsC8DymCcqlGkig8qLKcZ0hWJWVwiPJiFgL7laabXs++ZhCa4hdZo4iqlG729DE4gaV1mJVdoAagIUwLMo+y4NxFDu0r7I0/EO5nYcCrppGVVBYiGk7H4T6sXuhTkbNNqVmXtV3ch5bOlh7 [TRUNCATED] Thu Aug 31 01:07:25 UTC 2017 : Endpoint request body after transformations: { "city": "Seattle", "time": "morning", "day": "Wednesday", "name" : "John" } Thu Aug 31 01:07:25 UTC 2017 : Sending request to https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Received response. Integration latency: 328 ms Thu Aug 31 01:07:25 UTC 2017 : Endpoint response body before transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=c0475a28-8de8-11e7-8d3f-4183da788f0f, Connection=keep-alive, Content-Length=62, Date=Thu, 31 Aug 2017 01:07:25 GMT, X-Amzn-Trace-Id=root=1-59a7614d-373151b01b0713127e646635;sampled=0, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Method response body after transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-59a7614d-373151b01b0713127e646635, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Successfully completed execution Thu Aug 31 01:07:25 UTC 2017 : Method completed with status: 200
로그는 매핑 전에 수신되는 요청과 매핑 후 통합 요청을 보여줍니다. 테스트가 실패하면 로그는 원래 입력이 올바르거나 매핑 템플릿이 올바르게 작동하는지 여부를 평가하는 데 유용합니다.
API 배포
테스트 호출은 시뮬레이션이며 제한이 있습니다. 예를 들어 테스트 호출은 API에서 제정된 권한 부여 메커니즘을 우회합니다. 실시간으로 API 실행을 테스트하려면 먼저 API를 배포해야 합니다. API를 배포하려면 그 시점에 API의 스냅샷을 생성하는 단계를 생성합니다. 단계 이름은 API의 기본 호스트 이름 뒤에 기본 경로도 정의합니다. API의 루트 리소스는 단계 이름 뒤에 추가됩니다. API를 수정할 경우 변경 사항이 적용되기 전에 API를 새 단계 또는 기존 단계에 다시 배포해야 합니다.
API를 단계에 배포하려면
Deploy API(API 배포)를 선택합니다.
스테이지에서 새 스테이지를 선택합니다.
단계 이름에
test
를 입력합니다.참고
입력은 UTF-8로 인코딩된(현지화되지 않은) 텍스트여야 합니다.
(선택 사항) 설명에 설명을 입력합니다.
배포를 선택합니다.
스테이지 세부 정보에서 복사 아이콘을 선택하여 API의 호출 URL을 복사합니다. API 기본 URL의 일반적인 패턴은 https://
입니다. 예를 들어 api-id
.region
.amazonaws.com/stageName
beags1mnid
리전에서 생성되고 us-west-2
단계에 배포된 API(test
)의 기본 URL은 https://beags1mnid.execute-api.us-west-2.amazonaws.com/test
입니다.
배포 단계에서 API 테스트
배포된 API를 테스트할 수 있는 방법에는 여러 가지가 있습니다. URL 경로 변수 또는 쿼리 문자열 파라미터만 사용하는 GET 요청의 경우 브라우저에 API 리소스 URL을 입력할 수 있습니다. 다른 메서드의 경우 POSTMAN
cURL을 사용하여 API를 테스트하려면
-
인터넷에 연결된 로컬 컴퓨터에서 터미널 창을 엽니다.
-
POST /Seattle?time=evening
을 테스트하려면 다음을 수행합니다.다음 cURL 명령을 복사하여 터미널 창에 붙여 넣습니다.
curl -v -X POST \ 'https://beags1mnid.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -H 'x-amz-docs-region: us-west-2' \ -d '{ "callerName": "John" }'
다음 페이로드와 함께 성공적인 응답을 받아야 합니다.
{"greeting":"Good evening, John of Seattle. Happy Thursday!"}
이 메서드 요청에서
POST
를PUT
으로 변경할 경우 동일한 응답을 받습니다.
정리
이제 이 연습을 위해 생성한 Lambda 함수가 더 이상 필요하지 않은 경우 해당 함수를 삭제할 수 있습니다. 함께 제공되는 IAM 리소스도 삭제할 수 있습니다.
주의
이 시리즈의 다른 연습을 완료하려면 Lambda 실행 역할 또는 Lambda 호출 역할을 삭제하지 마십시오. API가 의존하는 Lambda 함수를 삭제할 경우 해당 API가 더 이상 작동하지 않습니다. Lambda 함수 삭제는 실행 취소할 수 없습니다. Lambda 함수를 다시 사용하려면 함수를 재생성해야 합니다.
Lambda 함수가 의존하는 IAM 리소스를 삭제할 경우 Lambda 함수가 더 이상 작동하지 않습니다. 따라서 해당 함수에 의존하는 모든 API가 더 이상 작동하지 않게 됩니다. IAM 리소스 삭제는 실행 취소할 수 없습니다. IAM 리소스를 다시 사용하려면 리소스를 재생성해야 합니다.
Lambda 함수를 삭제하려면
AWS Management Console에 로그인하고 AWS Lambdahttps://console.aws.amazon.com/lambda/에서
콘솔을 엽니다. -
함수 목록에서 GetStartedLambdaIntegration을 선택하고 작업을 선택한 다음 함수 삭제를 선택합니다. 확인 메시지가 나타나면 삭제를 다시 선택합니다.
연결된 IAM 리소스를 삭제하려면
https://console.aws.amazon.com/iam/
에서 IAM 콘솔을 엽니다. -
세부 정보에서 역할을 선택합니다.
-
역할 목록에서 GetStartedLambdaIntegrationRole을 선택하고 역할 작업을 선택한 다음 역할 삭제를 선택합니다. 콘솔의 단계에 따라 역할을 삭제합니다.