본문 바로가기

Networking/API Gateway

API Gateway, DynamoDB 사용 시 주의사항

API Gateway는 백단에 HTTP(S) / Lambda 뿐만 아니라, Dynamodb를 비롯한 AWS 서비스들을 바로 호출할 수 있다.

 

서버리스의 경우 Front(S3) -> Cognito -> API Gatway -> Lambda -> DynamoDB나 기타 DB 를 통해 CRUD를 구성할 수 있다.

 

간단한 서비스의 경우에는 Lambda 없이, API Gateway -> DynamoDB으로도 가능하다.

(가령, 크롤링 같은 경우 해당 구성이 가성비 최고인 듯...)

 

https://aws.amazon.com/ko/blogs/compute/using-amazon-api-gateway-as-a-proxy-for-dynamodb/

 

Using Amazon API Gateway as a proxy for DynamoDB | Amazon Web Services

Andrew Baird, AWS Solutions Architect Amazon API Gateway has a feature that enables customers to create their own API definitions directly in front of an AWS service API. This tutorial will walk you through an example of doing so with Amazon DynamoDB. Why

aws.amazon.com

 

여기서 주의사항의 경우 API Gateway Method 부분에서 HTTP Method를 POST로 지정해야 한다. 또한 Action에서도 GetItem, PutItem, Query 등 사용하고자 하는 DynamoDB Function을 기입해야 한다.

API Gateway Method

 

그럼 아래와 같이 Mapping Templates를 통해서 HTTP(S) 요청의 Header, URI Parameter, QueryString 그리고 Body까지 제어가 가능하다.

https://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html

 

API Gateway 매핑 템플릿과 액세스 로깅 변수 참조 - Amazon API Gateway

API Gateway 매핑 템플릿과 액세스 로깅 변수 참조 이 단원에서는 Amazon API Gateway가 데이터 모델, 권한 부여자, 매핑 템플릿, CloudWatch 액세스 로깅에 사용하기 위해 정의하는 변수 및 함수에 대한 참��

docs.aws.amazon.com

API Gateway Mapping Templates

 

아래 매핑 템플릿의 경우는 Hash Key 값이 object_name인 Dyanamodb batch_test 테이블에 Query Get 요청을 하는 경우다. 

{
    "TableName": "batch_test",
    "KeyConditionExpression": "object_name = :val",
    "ExpressionAttributeValues": {
        ":val": {
            "S": "$input.params('date')"
        }
    }
}

 

그럼 아래와 같이 "https://apigateway.com/day/2020-02.." Param 요청을 통해 데이터를 받아올 수 있다.

API Gateway

Query를 사용하는 이유는 DynamoDB 테이블을 Hash Key가 아닌 Hash, Range Key 두 가지를 사용할 경우 GetItem을 통해서는 데이터를 받아올 수 없기 때문이다.  (GetItem의 경우 Hash, Range Key가 둘 다 필요)

 

따라서 아래와 같은 Range, Hash Key를 사용하는 keyword_table과 같은 테이블의 경우 Hash Key인 date만으로 데이터를 받아오고 싶을 때 사용한다.

DynamoDB Table

그러나 동일하게 아래와 같은 매핑 템플릿을 사용하면 에러가 발생된다.

{
    "TableName": "keyword_table",
    "KeyConditionExpression": "date = :val",
    "ExpressionAttributeValues": {
        ":val": {
            "S": "$input.params('date')"
        }
    }
}

reserved keyword

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/GettingStarted.NodeJs.04.html

 

4단계: AWS SDK for JavaScript를 사용하여 DynamoDB에서 데이터 쿼리 및 스캔 - Amazon DynamoDB

ExpressionAttributeNames는 이름을 교체합니다. 이는 year가 Amazon DynamoDB의 예약어이기 때문입니다. 이를 KeyConditionExpression을 포함한 어떤 표현식에서도 직접 사용할 수 없습니다. 표현식 속성 이름인 #yr

docs.aws.amazon.com

이유는 위 참조 링크와 같이 매핑 테이블 안 KeyConditionExpression에는 DynamoDB의 예약어가 들어갈 수 없기 때문이다. 

 

따라서 만약 AttributeName에 year, date와 같은 DynamoDB의 예약어가 사용됐다면, ExpressionAttributeNames를 사용해서 아래와 같이 매핑 템플릿을 변경해줘야 한다.

{
    "TableName": "keyword_table",
    "KeyConditionExpression": "#date = :val",
    "ExpressionAttributeNames": {
        "#date": "date"
    },
    "ExpressionAttributeValues": {
        ":val": {
            "S": "$input.params('date')"
        }
    }
}

그럼 정상적으로 잘 호출된다.

API Gateway

 

QueryString을 이용할 경우 아래와 같이 querystring.get을 통해 사용도 가능하다.

{
    "TableName": "keyword_table",
    "KeyConditionExpression": "#date = :val and keyword = :val2",
    "ExpressionAttributeNames": {
        "#date": "date"
    },
    "ExpressionAttributeValues": {
        ":val": {
            "S": "$input.params().querystring.get('date')"
        },
        ":val2":{
           "S": "$input.params().querystring.get('keyword')"
        }
    }
}

 

너무 집약적인 문제지만 API Gateway, Dynamodb Query 관련 매핑 템플릿 관련 내용이 별로 없어 글을 남긴다. 

태그