AWS Lambda와 API Gateway를 이용해서 Serverless Web API 만들기
AWS Lambda 란 코드를 AWS 내에 올려두고 필요할 때에만 해당 코드를 실행해주는 서비스를 말합니다. 서버를 24시간 가동시키게 아니라, 그냥 해당 코드가 실행되면서 사용하는 컴퓨팅 시간에 대해서만 과금을 하는 방식입니다. 즉, 서버없이 서비스를 할 수 있는 편리한 구조면서도 실제로 코드가 동작하는 만큼만 과금이 되다보니 보통의 경우 서버를 띄워놓는거보다 훨씬 저렴한 비용으로 서비가 가능하며 스케일링에 대한 관리를 해줄 필요가 없습니다.
람다에 올려둔 코드는 AWS 내의 다른 서비스에서 이벤트 형식으로 해당 코드가 실행되게 할 수 있는데, API Gateway 를 붙이면 웹서비스로 활용이 가능합니다.
이 두가지 AWS의 서비스를 이용해서 서버없이 API 서비스를 구축하는 튜토리얼을 진행하겠습니다. 아무 생각없이 그냥 따라하시다 보면 그 과정과 원하는 값을 전달하고 받는 것에 대해서 이해가 되실 겁니다.
Lambda 생성
AWS로그인 후Lambda탭으로 이동

Create a Lambda Function선택

- Select blueprint에서
Blank Function선택

- Configure function 에서 일단 바로
Next선택 (미리 연결할 API Gateway가 있다면 여기서 연결하면 됨) Configure function에서 함수 정의- Name :
testLambda-luna - Runtime :
Node.js 4.3 - Code : 아래 코드를 입력
- 참고로
callback(null, result);와context.succeed(result);는 둘 다 결과를 return 해주는 코드로 아무거나 사용해도 됨
- 참고로
- Role & Existing role : 일단은 적당히 선택 (만약 Lambda에서 다른 AWS 서비스 RDS, S3 등을 연동할려면 필요)
- 아래 코드 입력 후
Next선택
- Name :
'use strict';
exports.handler = (event, context, callback) => {
let result = {"event" : event, "context" : context}
context.succeed(result);
//callback(null, result);
};
Create Function선택Action->Configure test event선택- 원하는 값으로 수정 후
Save and test선택하면 아래와 같이 나옴.
{
"event": {
"key3": "value3",
"key2": "value2",
"key1": "value1"
},
"context": {
"callbackWaitsForEmptyEventLoop": false,
"logGroupName": "/aws/lambda/testLambda-luna",
"logStreamName": "2016/11/16/[$LATEST]3906ef41b5df4f1d89c6501dda78253c",
"functionName": "testLambda-luna",
"memoryLimitInMB": "128",
"functionVersion": "$LATEST",
"invokeid": "be8f2961-aba7-11e6-8ffb-6d91b83819cf",
"awsRequestId": "be8f2961-aba7-11e6-8ffb-6d91b83819cf",
"invokedFunctionArn": "arn:aws:lambda:ap-northeast-1:768556645518:function:testLambda-luna"
}
}
- 만약
name이란 값을event로 넘겨서Hello+name을 출력하고 싶다면 위 Lambda Code를 아래와 같이 수정
'use strict';
exports.handler = (event, context, callback) => {
let result = {"event" : event, "context" : context}
let name = event.name || 'no name';
context.succeed('Hello ' + name);
};
- 그런 다음
Configure test event에name을 넣어주면 아래와 같이 출력됨.
{
"name" : "Luna"
}
"Hello Luna"
API Gateway 생성 & Lambda 연결
AWS메인 화면으로 이동 후API Gateway탭으로 이동

Create API선택- API name :
testAPI-luna Create API선택
- API name :
Actions->Create Resource선택 (API Path를 추가)- Resource name :
test - Resource Path :
test Create Resource선택
- Resource name :
/test가 선택된 상태에서Actions->Create Resource선택- Resource name :
name - Resource Path :
{name}(Path Variable 추가) Create Resource선택
- Resource name :
/{name}이 선택된 상태에서Actions->Create Method선택GET선택 후 확인- Lambda Region : 람다를 생성한 region 선택
- Lambda Function :
testLambda-luna(좀 전에 생성한 람다명 입력)

Integration Request선택Body Mapping Templates선택Add mapping template선택application/json입력No, use current settings선택
- Generate template:
Method Request passthrough선택Save선택
/test/{name} [GET]선택TEST선택- Path {name} : 원하는 값 입력
Test버튼 선택- 아래와 같이 출력되면 성공
{
"event": {
"body-json": {},
"params": {
"path": {
"name": "Luna"
},
"querystring": {},
"header": {}
},
"stage-variables": {},
"context": {
...
}
},
"context": {
"callbackWaitsForEmptyEventLoop": true,
"logGroupName": "/aws/lambda/testLambda-luna",
...
}
}
배포
Actions->Deploy API선택- Deployment Stage :
[New Stage]선택 - Stage name :
prod입력 Deploy버튼 선택Invoke URL복사
- Deployment Stage :

테스트
Invoke URL+/test/luna로 Web Browser에서 주소 입력- 위 JSON 같은 모양으로 출력되면 성공
Invoke URL+/test/luna?id=345;dept=개발팀과 같이 QueryString 을 포함하여 호출- 아래와 같이 querystring 에서 확인되면 성공
{
"event": {
"body-json": {},
"params": {
"path": {
"name": "Luna"
},
"querystring": {
"dept": "개발팀",
"id": "345"
},
...
}
}
}
POST로 배포
API Gateway에testAPI-luna로 이동/{name}이 선택된 상태에서Actions->Create Method선택POST선택 후 확인- Lambda Region : 람다를 생성한 region 선택
- Lambda Function :
testLambda-luna
- 바로
Test버튼을 눌러서 확인- Path {name} : 원하는 값 입력
- Request Body에 아래 JSON 값 입력
{
"id": "123",
"age": "25"
}
- 결과
{
"event": {
"id": "123",
"age": "25"
},
"context": {
...
}
}
name값이 정상적으로 전달되지 않았으므로GET작업한것 처럼 template 설정Integration Request선택Body Mapping Templates선택Add mapping template선택application/json입력No, use current settings선택
- Generate template:
Method Request passthrough선택Save선택
Test로 들어가서 위와 같은JSON입력
{
"event": {
"body-json": {
"id": "123",
"age": "25"
},
"params": {
"path": {
"name": "Luna"
},
"querystring": {},
"header": {}
},
...
}
}
다시 배포
Actions->Deploy API선택- Deployment Stage :
[New Stage]선택 - Stage name :
prod입력 Deploy버튼 선택Invoke URL복사
- Deployment Stage :
Postman 을 통해서 테스트
- 만약 설치되지 않았다면, Chrome App
Postman설치 후 실행 POST메서드로 선택- 주소에
Invoke URL+/test/luna?id=345입력 Headers탭 선택headerValue1:123입력

Body탭 선택- 위 예제의 JSON 입력

Send선택- 결과
{
"event": {
"body-json": {
"id": "123",
"age": "25"
},
"params": {
"path": {
"name": "luna"
},
"querystring": {
"id": "345"
},
"header": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4",
...
"Content-Type": "application/json",
"headerValue1": "123",
...
}
},
"stage-variables": {},
"context": {
...
"http-method": "POST",
...
"source-ip": "112.217.228.202",
"user": "",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
...
"resource-path": "/test/{name}"
}
}
},
"context": {
...
}
}
활용
Lambda에서 전달받은 값 활용eventbody-json: BODY에서 전달해온 값paramspath: URL 상에서 경로로 얻어오는 변수들
header: HEADER에서 전달해온 값querystring: URL 상의 QueryString로 전달된 변수들contexthttp-method: 호출한 METHOD (GET, POST, …)resource-path: 하나의 Lambda에서 여러 URL을 처리할 경우 경로 정보
참고
- 아웃사이더님 Blog : https://blog.outsider.ne.kr/1205 , https://blog.outsider.ne.kr/1206
- 원문 : https://github.com/DevStarSJ/Study/blob/master/Blog/Cloud/AWS/Lambda%2BAPIGateWay.01.md
잘못되었거나, 변경된 점, 기타 추가 사항에 대한 피드백은 언제나 환영합니다. - seokjoon.yun@gmail.com
다음글
다른 글 목록
- Lambda 와 API Gateway 연동 #1 (GET, POST)
- Lambda 와 API Gateway 연동 #2 (ANY, Deploy Staging, Node.JS Route)
- Lambda 와 API Gateway 연동 #3 (Proxy Resource)
- Lambda Node.JS Packaging
- AWS Lambda에 Python Handler 만들기
- Lambda Python Packaging
- AWS Lambda에 C# Handler 만들기
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)
