AWS Lambda 및 DynamoDB를 이용하여 간단한 CRUD API 만들기

이동명·2024년 1월 18일
0

Serverless

목록 보기
2/3
post-thumbnail

개요

저번 포스팅에 이어서 진행할 예정이고 순서는 다음과 같다. 아래의 순서는 AWS-documentaion을 참고하였음.

  1. DynamoDB 테이블 생성
  2. Lambda 함수 생성
  3. HTTP API 생성
  4. 경로 생성
  5. 통합 생성
  6. 경로에 통합 연결
  7. API 테스트
  8. 정리

[docs 참고]

DynamoDB 테이블 생성

일단 기본 설정으로 만들자. 읽기용량 과 쓰기용량은 프리티어 에서 25RCU, 25WCU 까지 무료료 지원 된다고 한다.

Lambda 함수 생성

기본 정보 적어주고..

AWS 정책 템플릿에서 새 역할 생성 으로 설정하자.

그리고 간단한 템플릿을 만들어볼거니까 role을 추가해주자.

생성이 되면 아래의 템플릿을 index.mjs에 붙여넣어주고 deploy를 누르자.

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  ScanCommand,
  PutCommand,
  GetCommand,
  DeleteCommand,
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});

const dynamo = DynamoDBDocumentClient.from(client);

const tableName = "http-crud-tutorial-items";

export const handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json",
  };

  try {
    switch (event.routeKey) {
      case "DELETE /items/{id}":
        await dynamo.send(
          new DeleteCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = `Deleted item ${event.pathParameters.id}`;
        break;
      case "GET /items/{id}":
        body = await dynamo.send(
          new GetCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = body.Item;
        break;
      case "GET /items":
        body = await dynamo.send(
          new ScanCommand({ TableName: tableName })
        );
        body = body.Items;
        break;
      case "PUT /items":
        let requestJSON = JSON.parse(event.body);
        await dynamo.send(
          new PutCommand({
            TableName: tableName,
            Item: {
              id: requestJSON.id,
              price: requestJSON.price,
              name: requestJSON.name,
            },
          })
        );
        body = `Put item ${requestJSON.id}`;
        break;
      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
  };
};

HTTP API 생성

유형은 여러가지가 있지만 HTTP API 로 선택하자. 차이는 나중에 정리해야겠다.

구축 하고 다음 버튼을 누르고 생성하면 아래의 그림처럼 생성이 된다.

경로 생성

방금 만들었던 http API 를 선택해서 경로를 생성하자.

경로 끝의 {id}은(는) 클라이언트가 요청을 할 때 API Gateway가 요청 경로에서 검색하는 경로 파라미터입니다.

GET /items, DELETE /items/{id} 및 PUT /items 을 총 4개를 입력해줍시다.

통합 생성

생성한 api 의 Integrations 메뉴로 접근하자.

생성하고 이 통합을 경로에 연결은 건너뛰어주자. 통합 대상 탭에서 lambda function을 선택하고 아래처럼 내 lambda를 골라주면 된다.

생성하면 아래와 같은 명세를 볼 수 있다. (페이로드 형식 버전도 유의해야 한다)

경로에 통합 연결

기존 통합 메뉴 탭에서 연결해주면 된다.

경로마다 다 해주면 됨

API 테스트

api 까지 다 완성 되었기 때문에 이제 test를 해 볼 차례이다. 아래의 네모에서 확인하면 되고 오른쪽 네모는 테스트 url이다.

get요청을 테스트 해보니 200을 반환한다.

람다의 스펙을 최소로 해서 1.38초가 걸리는 모습

put 요청 또한 정상적으로 반환.

여러개 넣고 다시 GET 으로 확인한 모습, 파라미터로 id를 넣어주면 해당 정보를 받아오게 된다. delete도 마찬가지이다.

CORS 대응

CORS docs 를 참고하자.

아래처럼 설정해주자,

정리

dynamoDB > http API > Lambda 함수 > Lambda 함수의 로그 그룹 > Lambda 함수의 실행 역할 순으로 삭제하면 된다.


REST API

REST API 는 db생성 > lambda 함수 생성 까지는 같은데 lambda를 생성하고 나서 index.mjs의 코드가 살짝 다르다. 이유는 payload 버전에 따른 json포맷 때문에 그렇다고 한다. 자습서에 있으니 참고하자.


dynamoDB 에 주기적으로 값 넣어주기

이 전 실습때 했던 dynamoDB 와 lambda는 그대로 사용하고..
lambda 의 index.mjs 만 수정을 좀 해주자.

기존 switch 문은 제거하였고 주기적으로 넣어 줄 데이터 형식만 작성하였다.

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  PutCommand
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});

const dynamo = DynamoDBDocumentClient.from(client);

const tableName = "http-crud-tutorial-items";

export const handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json",
  };

  try {
    await dynamo.send(
      new PutCommand({
        TableName: tableName,
        Item: {
          id: String(Date.now()),
          price: 1,
          name: "name",
        },
      })
    );
    body = `Put item ${String(Date.now())}`;
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
  };
};

deploy 후 test 를 해보면 다음과 같은 결과를 얻을 수 있다.

그 후 dynamoDB쪽에서 데이터가 잘 들어왔음을 확인할 수 있다.

잘 들어오는 걸 확인했으니 이를 1분마다 작동시켜보자. 아래의 트리거 추가 버튼을 누르자.

아래 처럼 옵션을 설정해주고 아래에는 linux crontap 처럼 schedule규칙을 정할 수 있다. 옆의 링크에 자세하게 나와있다.

그리고 추가 하였다.

1분 마다 이벤트가 실행되는 모습.


다음 포스팅은 개념 보강을 위해 간단한 주제로 미니 프로젝트 포스팅을 진행하도록 하겠다.

profile
Web Developer

0개의 댓글