본문 바로가기

Graduation Project

API Gateway + Lambda로 REST API 만들기

HTTP 요청을 사용하여 Lambda 함수를 호출하는 REST API를 생성하고자 합니다.

 

위의 이미지에서 API Gateway, Lambda까지만 구성합니다. 

전반적인 과정은 AWS 자습서: API Gateway에서 Lambda 사용 을 참고합니다.

 

순서는 다음과 같습니다.

1. 사전 조건

2. 권한 정책 생성 및 실행 역할 생성

3. Lambda 함수 생성

4. API Gateway 생성

5. 함수 호출 테스트 진행

 

 

사전 조건

AWS 계정 가입

현재 새로운 프로젝트를 진행하고자하면 새로운 계정을 생성하는 것이 좋습니다.

새로운 계정을 생성하면 1년동안 프리티어의 혜택을 받을 수 있습니다. 

Lambda 프리 티어에는 월 100만 건의 무료 요청과 월 40만 GB-초의 컴퓨팅 시간이 포함되어 있으며 x86 및 Graviton2 프로세서로 구동되는 기능에 모두 사용할 수 있습니다. 또한 프리 티어에는 요청당 첫 6MB를 초과하는 월별 100GiB의 HTTP 응답 스트리밍이 무료로 포함됩니다.

관리 사용자 생성

AWS 계정에 가입하고 AWS 계정 루트 사용자를 보안하며 일상적인 작업에 루트 사용자를 사용하지 않도록 IAM에서 관리 사용자를 생성합니다.

관리 사용자 계정을 만드는 방법은 아래 링크를 참조했습니다.

관리용 IAM 사용자 계정 생성

 

권한 정책 생성 및 실행 역할 생성

권한 정책 생성

Lambda 함수의 실행 역할을 생성하려면 먼저 권한 정책을 생성하여 필요한 AWS 리소스에 액세스할 권한을 함수에 부여해야 합니다. 

저는 사전에 만들어져 있는 권한 정책을 연결하려고 하기 때문에 이 부분은 생략하겠습니다.

실행 역할 생성

실행 역할은 AWS 서비스 및 리소스에 액세스할 수 있는 권한을 Lambda 함수에 부여하는 IAM 역할입니다. 

  1. IAM 콘솔에서 역할 페이지를 엽니다.
  2. 역할 생성을 선택합니다.
  3. 신뢰할 수 있는 엔터티의 유형으로 AWS 서비스를 선택한 다음 사용 사례로 Lambda를 선택합니다.
  4. 다음을 선택합니다.
  5. 정책 리스트들 중에 필요한 정책들을 추가합니다. 저는 람다에서 DynamoDB와 S3에 접근하기 위해서 AmazonDynamoDBFullAccess, AmazonS3FullAccess를 연결했습니다.
  6. Role details(역할 세부 정보)에서 Role name(역할 이름)에 역할 이름을 입력한 다음 Create role(역할 생성)을 선택합니다.

 

Lambda 함수 생성

일단 콜드스타트가 적은 node.js로 함수를 개발하고자 합니다. 현재 Lambda는 node.js 18, 16, 14를 지원하고있으며 새로 출시된 20은 아직 지원하지 않기 때문에 18버전으로 개발하고자 합니다.

간단하게 함수를 생성하기 위해 Lambda 콘솔을 사용했습니다.

  1. Lambda  Gateway 콘솔을 엽니다.
  2. 함수 생성을 선택합니다.
  3. 함수 이름, 런타임, 아키텍쳐를 입력합니다.
  4. 기본 실행 역할 변경에서 기존 역할 사용을 클릭하고 위에 생성한 역할을 연결합니다.
  5. 함수 생성을 선택합니다.

람다의 파일 구조는 아래와 같이 생성하고자 합니다.

기존의 다른 람다의 구성과는 다르게 src 폴더 안에 index.js가 존재합니다. 

- lambda
    - src
    	- index.js
        - controller.js
        - service.js
    - package.json
    - package-lock.json

 

ES6를 사용하기 위해 package.json에 "type": "module"을 추가합니다.

package.json에 type을 추가

src 폴더 안에 index.js가 존재하므로 핸들러 주소도 다시 설정해야합니다.

런타임 설정 안에 핸들러에서 이를 수정합니다.

 

API Gateway 생성

먼저 API Gateway를 생성합니다.

  1. API Gateway 콘솔을 엽니다.
  2. API 생성(Create API)을 선택합니다.
  3. REST API 상자에서 빌드를 선택합니다.
  4. API 세부 정보에서 새 API를 선택한 상태로 두고 API 이름 <API 이름>을 입력합니다.
  5. API 생성(Create API)을 선택합니다.

API Gateway를 생성한 후에 메서드를 생성합니다.

  1. API에서 경로를 선택합니다.
  2. 함수를 호출하고 싶은 경로를 직접 생성합니다. 이때 path parameter를 넣고자 한다면 {path parameter }로 입력하면 된다.
  3. 통합 유형에서 Lambda 함수를 선택한 상태로 둡니다.
  4. Lambda 함수에서 함수의 Amazon 리소스 이름(ARN)을 선택합니다.

API를 배포합니다.

스테이지를 $default로 사용하면 자동 배포가 진행됩니다. 간단한 구성을 위해 이대로 진행했습니다.

 

AWS 문서에서는 API gateway에서 테스트를 하는 탭이 존재한다고 적혀있는데 UI가 업데이트되면서 찾을 수 없습니다...

 

 

함수 호출 테스트 진행

위의 과정을 완료하면 아래와 같은 URL을 확인할 수 있습니다.

해당 URL을 baseURL로 사용하며 포스트맨과 같은 호출 프로그램으로 직접 테스트할 수 있습니다.

 

event의 형태는 다음과 같습니다.

 

pathParameters가 있는 경우

{
    "version": "2.0",
    "routeKey": "GET /roleplay/official/{templateID}",
    "rawPath": "/roleplay/official/1",
    "rawQueryString": "",
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "content-length": "0",
        "host": "xxxxx.execute-api.ap-northeast-2.amazonaws.com",
        "postman-token": "8a1b4c77-8f8f-4de4-9fc7-10380464aa15",
        "user-agent": "PostmanRuntime/7.36.0",
        "x-amzn-trace-id": "Root=1-657ce4ef-16406eb8046221334222232c",
        "x-forwarded-for": "xxx.xxx.xxx.xxx",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "requestContext": {
        "accountId": "xxxxxxxxxx",
        "apiId": "xxxxxxxxx",
        "domainName": "xxxxxxxx.execute-api.ap-northeast-2.amazonaws.com",
        "domainPrefix": "xxxxxxxx",
        "http": {
            "method": "GET",
            "path": "/roleplay/official/1",
            "protocol": "HTTP/1.1",
            "sourceIp": "xxx.xxx.xxx.xxx",
            "userAgent": "PostmanRuntime/7.36.0"
        },
        "requestId": "xxxxxxxx=",
        "routeKey": "GET /roleplay/official/{templateID}",
        "stage": "$default",
        "time": "15/Dec/2023:23:44:47 +0000",
        "timeEpoch": 1702683887232
    },
    "pathParameters": {
        "templateID": "1"
    },
    "isBase64Encoded": false
}

 

queryStringParameters 가 있는 경우

{
    "version": "2.0",
    "routeKey": "GET /roleplayList/official",
    "rawPath": "/roleplayList/official",
    "rawQueryString": "pet=dog",
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "authorization": "Bearer XXXXX.XXXXX.XXXXXX",
        "content-length": "0",
        "host": "XXXXXXXX.execute-api.ap-northeast-2.amazonaws.com",
        "postman-token": "c833dde2-1a9b-4dd9-88bb-853129aec31a",
        "user-agent": "PostmanRuntime/7.36.3",
        "x-amzn-trace-id": "Root=1-65ce3ccf-30c3fc674e381a2516d1bbeb",
        "x-forwarded-for": "xxx.xxx.xxx.xxx",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "queryStringParameters": {
        "pet": "dog"
    },
    "requestContext": {
        "accountId": "xxxxxx",
        "apiId": "xxxxxxx",
        "domainName": "xxxxxxxx.execute-api.ap-northeast-2.amazonaws.com",
        "domainPrefix": "xxxxxxx",
        "http": {
            "method": "GET",
            "path": "/roleplayList/official",
            "protocol": "HTTP/1.1",
            "sourceIp": "175.119.241.142",
            "userAgent": "PostmanRuntime/7.36.3"
        },
        "requestId": "xxxxxxxxxx=",
        "routeKey": "GET /roleplayList/official",
        "stage": "$default",
        "time": "15/Feb/2024:16:33:19 +0000",
        "timeEpoch": 1708014799945
    },
    "isBase64Encoded": false
}