본문 바로가기
서버/AWS

[AWS]17. 웹 Serverless Architecture 구성

by jamong1014 2024. 3. 19.
반응형

Serverless 구성( Route53, Cloudfront, DAX 등 솔루션들은 나중에 프로젝트 제작할 때 추가로 넣을 예정 )

 

목차

  1. DynamoDB 생성
  2. Lambda 함수 생성
  3. DynamoDB Stream 이벤트 트리거 추가
  4. API Gateway 생성
  5. 결과 확인 및 원리

* SNS 솔루션 등 구체적인 생성 방법이나 IAM 권한 정책 할당은 생략함


1. DynamoDB 생성

파티션 키 타입은 테이블 목적에 따라서 설정하면 된다.

(다른 구체적인 설정이 필요하면 클래스 선택(standard, standard-IA) 하면 됨)

 

이후에 이제 DynamoDB Stream을 생성해야 하는데 먼저 Lambda 함수를 생성해줘야 한다.


2. Lambda 함수 생성

DynamoDB 테이블에서 데이터를 스캔하고, 해당 데이터를 JSON 형식으로 반환하는 코드

 

import json
from decimal import Decimal
import boto3


REGION = 'ap-northeast-2'

dynamodb = boto3.resource('dynamodb', region_name=REGION)
table = dynamodb.Table('study_test')

def convert_decimal_to_str(obj):
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError

def lambda_handler(event, context):
    try:
        response = table.scan()
        # Decimal 값을 문자열로 변환하여 직렬화
        data = response['Items']
        serialized_data = json.dumps(data, default=convert_decimal_to_str)
        return {
            'statusCode': 200,
            'body': serialized_data
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

* convert_decimal_to_str() 함수는 Decimal 타입의 객체를 문자열로 변환.

DynamoDB에서 숫자 형식의 데이터는 Decimal 형식으로 반환되므로, JSON 직렬화 시에 문제가 발생할 수 있어서 문자열로 변환하여 JSON에 포함될 수 있도록 함

 

import json
from decimal import Decimal
import boto3
from boto3.dynamodb.conditions import Key

REGION = 'ap-northeast-2'

dynamodb = boto3.resource('dynamodb', region_name=REGION)
table = dynamodb.Table('study_test')

def convert_decimal_to_str(obj):
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError

def lambda_handler(event, context):
    try:
        response = table.query(
            KeyConditionExpression=Key('idx').eq('2024-03-17 16:57:43')
        )
        data = response['Items']
        serialized_data = json.dumps(data, default=convert_decimal_to_str)
        return {
            'statusCode': 200,
            'body': serialized_data
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

KeyConditionExpression을 이용해서 eq 연산자를 통해 특정 행을 출력


3. DynamoDB Stream 이벤트 트리거 추가

 

DynamoDB 테이블에서 트리거 생성 선택

 

방금 생성했던 Lambda 함수를 선택 후 생성

 

그럼 Lambda 트리거 목록에 DynamoDB 트리거가 생성된 걸 확인할 수 있다.

이제 API Gateway를 생성해 보자

 


4. API Gateway 생성

 

API Gateway REST API 구축
메서드 생성

기존의 생성했던 Lambda 함수와 연결(메서드 : GET)

 

리소스 생성
스테이지 생성

 

리소스는 API의 엔드포인트를 정의하고 그룹화하며, 스테이지는 API의 배포된 버전을 나타내며 엔드포인트 URL을 제공

 

배포된 API의 엔드 포인트 URL을 통해 클라이언트에서 요청을 보내야 하는데 웹 애플리케이션에서 보안 상의 이유로 다른 출처(Origin)로부터 리소스를 요청할 때 발생하는 보안 정책으로 인해 CORS를 활성화하여 Access-Control-Allow-Headers를 추가해야 함

 

*그리고 API 재배포


5. 결과 확인 및 원리

두 개의 트리거가 생성된 걸 볼 수 있음

 

테스트를 통해서 DynamoDB의 테이블을 스캔하여 JSON 형식으로 반환하는 것을 볼 수 있음

 

API 엔드포인트를 통해서도 URL로 확인할 수 있다.

 

* 웹 클라이언트를 제작할 땐 API 엔드포인트 URL을 통해서 비동기식으로 제작하면 됨 (이때 CORS 정책을 활성화해야 정상적으로 엔드포인트 URL을 호출할 수 있음)

 

원리

  1. DynamoDB Stream을 통해 테이블의 변화를 실시간으로 탐지하고 이벤트 트리거를 생성하여 Lambda 함수 호출
  2. 호출된 코드에 의해 테이블을 스캔하여 저장된 데이터들을 JSON 형식으로 변환하고 반환
  3. 클라이언트가 REST API의 엔드포인트 URL로 데이터를 요청하면 반환된 데이터를 확인할 수 있음

 

이런 식으로 서버리스 아키텍처를 구성해서 로그인/회원가입 등등의 다른 동적인 처리도 모두 처리할 수 있음

 

반응형

댓글