BLOG
REST (Representational State Transfer) API는 분산 시스템의 일반적인 아키텍처 스타일입니다. Stateless의 장점을 바탕으로 워크로드가 증가함에 따라 효율적인 확장이 가능합니다. 편리하지만 강력한 API는 데이터베이스 시스템과 연계되어 데이터베이스 내 데이터에 대한 프로그래밍 방식 액세스를 제공하기도 합니다. 지난번 고객분으로부터 Amazon DocumentDB (MongoDB 호환성 포함) 데이터베이스에 액세스할 수 있는 REST API를 요청 받은 적이 있어 오늘은 이에 대해 다뤄보도록 하겠습니다.
Amazon DocumentDB는 MongoDB 워크로드를 지원하는 빠르고 확장 가능하며 가용성이 높은 완전 관리형 문서 데이터베이스 서비스입니다. 문서 데이터베이스인 Amazon DocumentDB를 사용하면 JSON 데이터를 쉽게 저장, 쿼리 및 인덱싱할 수 있습니다. 사용자가 Amazon DocumentDB와 상호 작용하는 데 사용하는 기본 메커니즘은 steteful 세션 기반 API를 제공하는 MongoDB 드라이버를 사용하는 것입니다.
Amazon DocumentDB에 대한 간단한 HTTP 기반 액세스를 제공함으로써 웹 페이지, 기타 서비스 및 마이크로 서비스, 데이터베이스 액세스가 필요한 기타 애플리케이션에 문서 데이터를 추가할 수 있습니다.
본 게시물에서는 Amazon API Gateway, AWS Lambda 및 AWS Secrets Manager 를 사용하여 Amazon DocumentDB에 대한 읽기 및 쓰기 액세스를 위한 REST API를 구축하는 방법을 보여줍니다.
솔루션 개요
오늘 예제에서 REST API는 Amazon DocumentDB 컬렉션에 대해 삽입, 업데이트, 삭제 및 읽기 작업을 수행할 수 있습니다. 특정 컬렉션, 특정 데이터베이스의 모든 컬렉션 또는 모든 데이터베이스의 모든 컬렉션에 대해 액세스를 제한할 수 있습니다. 이를 위해 다음 서비스를 사용하겠습니다.
- Amazon DocumentDB – 데이터 저장
- API Gateway – HTTP REST API 노출
- Lambda – API Gateway 서비스를 데이터베이스에 연결
- Secrets Manager – Lambda 함수에서 사용할 데이터베이스 자격 증명
API 엔드포인트 확보 모범 사례는 이 게시물에서 다루지 않으니 자세한 내용은 API Gateway에서 REST API에 대한 액세스 제어 및 관리를 참고하세요. 이 게시물에서는 간단한 사용자 이름-암호 인증이 다른 Lambda 함수로 제공됩니다. 다음 다이어그램은 이 솔루션의 아키텍처를 보여줍니다.
이와 같은 서버리스 애플리케이션을 배포할 때 선호되는 방식이므로 이 스택을 배포할 때 AWS Serverless Application Model(AWS SAM)를 사용합니다. 템플릿과 코드는z GitHub 저장소에서 보실 수 있습니다.
API 기능 측면에서 데이터베이스에 저장된 데이터에 대한 삽입, 업데이트, 삭제 및 찾기 작업이 나타납니다.
Amazon DocumentDB로 데이터 저장 (MongoDB 호환)
Amazon DocumentDB는 MongoDB 워크로드를 지원하는 빠르고 확장 가능하며 가용성이 높은 완전 관리형 문서 데이터베이스 서비스입니다. Amazon DocumentDB의 아키텍처, 가치 제안 및 속성에 대한 자세한 내용은 Amazon DocumentDB (MongoDB 호환성 포함)에 대해 알아야 할 12 가지 사항을 참고하세요. 이 게시물은 REST API를 통해 애플리케이션에 노출하는 기존 Amazon DocumentDB 클러스터로 시작합니다. Amazon DocumentDB 클러스터가 아직 없는 경우 Amazon DocumentDB 시작하기 (MongoDB 호환성 포함)를 참고하세요.
Secrets Manager를 사용하여 데이터베이스 자격 증명 저장
Lambda 함수를 포함하여 Amazon DocumentDB에 연결하는 AWS에 배포된 애플리케이션과 마찬가지로, Amazon DocumentDB에 연결하기 위한 자격 증명을 저장하는 데 Secrets Manager를 사용합니다. 이렇게 하면 Lambda 함수를 실행하는 데 사용되는 역할과 같은 역할에 이러한 자격 증명에 액세스할 수 있는 권한을 부여할 수 있습니다. 애플리케이션 또는 Lambda 함수가 Secrets Manager에서 자격 증명을 검색한 후 해당 자격 증명을 사용하여 Amazon DocumentDB에 데이터베이스를 연결할 수 있습니다.
API Gateway로 REST API 공개
이 게시물에서는 API Gateway를 사용하여 REST API를 공개합니다. API Gateway는 여러 API를 지원하며 REST는 옵션 중 하나일 뿐이지만 이 게시물에서는 이를 중점적으로 다뤄보겠습니다.
API Gateway는 REST 엔드포인트를 정의하고 해당 엔드포인트에 대한 작업을 정의할 수 있습니다. 이 논의에서는 컬렉션당 엔드포인트가 사용되며 해당 엔드포인트에 대한 여러 작업, 특히 다음과 같이 정의됩니다.
- GET – 데이터베이스 읽기 또는 찾기 작업에 해당
- PUT 또는 POST – 데이터베이스 삽입 작업에 해당
- PATCH – 데이터베이스 업데이트 작업에 해당
- DELETE – 데이터베이스 삭제 작업에 해당
해당 작업과 함께 전송되는 매개 변수는 해당 데이터베이스 작업의 매개 변수를 모방합니다. 예를 들어 GET 작업은 MongoDB API의 find () 작업을 모방합니다. MongoDB API에서 find () 작업에 5 개의 매개 변수를 지정할 수 있습니다.
- 관심 문서를 식별하는 필터로, JSON 객체로 지정됩니다.
- 반환해야 하는 필드를 지정하는 프로젝션으로 JSON 개체로 지정됩니다.
- 결과의 순서를 지정하는 정렬로, JSON 객체로 지정됩니다.
- 반환할 결과 수를 지정하는 제한으로, 정수로 지정됩니다.
- 결과를 반환하기 전에 건너뛸 결과 수를 지정하는 건너뛰기 양으로, 정수로 지정됩니다.
마찬가지로 PATCH 작업은 MongoDB API의 update () 작업을 모방하며 다음 두 매개 변수를 사용합니다.
- 업데이트해야 하는 문서를 식별하는 필터로, JSON 객체로 지정됩니다.
- 적용해야 하는 업데이트를 나타내는 업데이트 명령으로, JSON 개체로 지정됩니다.
- 업데이트에는 필드 값 설정 또는 설정 해제, 필드 값 증가 또는 감소 등이 포함됩니다.
MongoDB API에 대한 자세한 정보는 MongoDB 문서를 참고하세요.
REST 엔드포인트의 경로를 사용하여 작동할 데이터베이스 및 컬렉션을 지정합니다. API Gateway에서 정확한 경로를 지정하여 특정 데이터베이스 및 컬렉션을 지정할 수 있으며 REST 엔드포인트를 호출하는 클라이언트는 이를 변경할 수 없습니다. 예를 들어 API Gateway는 mydb 데이터베이스 http://<BASE_URL>/docdb/mydb/mycollection의 mycollection컬렉션에 액세스하는 것과 같은 URL을 노출할 수 있습니다.
또한 API Gateway에서 특정 REST 엔드포인트에 경로 변수를 추가하도록 허용할 수 있습니다. 이를 통해 특정 데이터베이스에 엔드포인트를 노출할 수 있지만 사용자가 컬렉션을 지정할 수 있습니다. 이를 통해 특정 데이터베이스의 모든 컬렉션에 액세스할 수 있습니다. 예를 들어 API Gateway는 호출자가 URL에 특정 컬렉션 이름을 추가할 수 있도록 하는 http://<BASE_URL>/docdb/mydb/another_collection과 같은 URL을 http://<BASE_URL>/docdb/mydb처럼 노출할 수 있습니다. 이를 통해 데이터베이스 mydb내 another_collection내부를 포함한 모든 컬렉션에 액세스할 수 있습니다.
이 아이디어를 더 확장하고 REST 엔드포인트를 노출하고 클라이언트가 데이터베이스와 컬렉션을 경로 변수로 지정하도록 허용하여 모든 데이터베이스의 모든 컬렉션을 노출할 수 있습니다. 예를 들어 API Gateway는 http://<BASE_URL>/docdb/와 같은 호출자가 데이터베이스와 컬렉션 이름을 http://<BASE_URL>/docdb/other_db/other_collection와 같은 URL에 추가할 수 있도록 합니다. 이를 통해 other_collection데이터베이스를 포함한 모든 데이터베이스 내부를 포함한 모든 컬렉션에 액세스 할 수 있습니다.
API Gateway 보안 적용
보안 관점에서 모범 사례로서 이러한 엔드포인트에 대한 액세스는 API Gateway의 보안 메커니즘을 통해 제한되어야 합니다. 자세한 내용은 API Gateway에서 REST API에 대한 액세스 제어 및 관리를 참고하세요. API Gateway에는 Amazon Cognito, AWS Identity and Access Management(IAM) 및 Lambda 함수를 포함하여 사용 가능한 여러 권한 부여 체계가 있습니다. 이 게시물에서는 제공된 사용자 이름과 암호를 정적 값 (Lambda 함수에 환경 변수로 저장됨)과 비교하는 간단한 Lambda 권한 부여자를 사용합니다. 일부 또는 모든 API 엔드포인트를 보호하고 다른 엔드포인트를 다르게 보호하도록 선택할 수도 있지만 (예: 다른 사용자 이름 / 비밀번호 쌍 또는 다른 권한 부여자 사용) 이는 이 게시물에서는 다루지 않습니다.
Lambda를 사용하여 API Gateway를 데이터베이스에 연결
이 솔루션에서 번거로운 작업을 수행하는 구성 요소는 Lambda입니다. GET (찾기용), PUT 또는 POST (삽입용), PATCH (업데이트용) 및 DELETE (삭제용)와 같이 노출된 모든 다양한 작업을 수행하기 위해 간단한 단일 Lambda 함수를 사용합니다.
API Gateway가 Lambda 함수를 호출하면 수신 이벤트에는 호출된 REST 메서드를 포함하여 여러 메타 데이터가 포함됩니다. 이 함수는 해당 필드를 사용하여 호출할 하위 함수를 결정하고 결과를 반환합니다. 또한 호출된 API 경로도 이벤트 일부로 전송됩니다. 이 경로는 쿼리할 데이터베이스 및 컬렉션을 결정하는 데 사용할 수 있습니다.
이 Lambda 함수를 구현하기 위한 몇 가지 모범 사례에 대해 이야기해 볼 가치가 있습니다.
Lambda 계층 사용
Lambda에는 일반적으로 사용되는 일부 라이브러리 또는 패키지를 패키징 할 수 있는 메커니즘이 있으므로 배포하는 각 Lambda 함수와 함께 패키징 할 필요가 없습니다. 예를 들어, Amazon DocumentDB에 연결하는 Python에서 Lambda 함수로 많은 작업을 수행하므로 대부분의 함수에는 연결을 위해 MongoDB 드라이버가 필요합니다. SSL을 사용하여 클러스터와 통신하는 모범 사례 구성을 사용하고 있기 때문에 함수에도 Amazon DocumentDB에 연결하기 위한 인증서 파일이 필요합니다.
이러한 종속성을 .zip 파일로 패키징하고 Lambda 계층을 생성할 수 있습니다. 그런 다음이 REST API에 대한 CRUD 작업 함수와 같은 Lambda 함수를 생성할 때 함수에 계층을 추가하여 이러한 종속성을 가져올 수 있습니다. 이렇게 하면 Lambda 함수 배포가 크게 단순화됩니다. 이제 종속성이 이미 패키징되어 있으므로 AWS Management Console에서 직접 Lambda 함수를 쉽게 구성할 수 있습니다. 또한 Lambda 함수가 간단한 경우 AWS CloudFormation 템플릿에 직접 함수의 소스 코드를 포함하여 자동화된 배포도 단순화할 수 있습니다.
이 게시물에서는 MongoDB Python 드라이버와 Amazon DocumentDB 인증서 파일을 포함하는 단일 Lambda 계층을 생성합니다. Python Lambda 함수에 추가하면 / opt 디렉터리에서 리소스를 사용할 수 있습니다.
Amazon DocumentDB에 연결
Lambda 함수에 대한 핸들러 내에서 Amazon DocumentDB에 연결하는 경우 Lambda 함수를 호출할 때마다 데이터베이스에 연결하는 프로세스를 거쳐야 합니다. 이는 연결에 대한 효율적이지 못하고 번거로운 접근 방식입니다.
Lambda 함수에서 액세스하는 다른 데이터베이스 서비스와 마찬가지로 모범 사례는 핸들러 자체 외부에서 연결하는 것입니다. AWS가 다른 Lambda 호출을 위해 환경을 재사용하면 이미 연결이 이루어진 것입니다. 이 게시물에서는 연결을 전역 변수에 저장하고 초기화되지 않은 경우 해당 연결을 사용합니다. 이 경우 데이터베이스 연결 하위 함수를 호출합니다.
Lambda 보안 적용
앞서 언급했듯이 Amazon DocumentDB 클러스터에 대한 자격 증명을 Secrets Manager에 저장합니다. Lambda 함수가 사용하는 역할에 이 암호를 검색할 수 있는 권한을 부여합니다. 이러한 자격 증명을 검색하는 Lambda 함수에 하위 함수를 추가하는 것은 간단한 작업입니다. 그러면 데이터베이스에 연결하는 데 사용할 수 있습니다.
이 패턴을 사용하면 코드나 Lambda 함수 구성에서 사용자 이름이나 암호를 노출하지 않는 좋은 방법입니다.
Amazon Document DB 클러스터에서 REST API 생성
이제 Amazon DocumentDB 클러스터용 REST API를 생성하는 단계를 살펴보겠습니다. 이 예에서는 현재 Amazon DocumentDB 클러스터가 있고 해당 클러스터에서 컬렉션을 쿼리할 수 있는 사용자의 사용자 이름과 암호를 알고 있다고 가정합니다. 현재 Amazon DocumentDB 클러스터가 실행되고 있지 않은 경우 다음 CloudFormation 템플릿을 사용하여 클러스터를 시작하세요.
이 REST API를 배포하기 위해 AWS SAM과 다음 리포지토리를 사용합니다. 이 리포지토리의 중요한 파일은 템플릿 파일, template.yaml에있는 Lambda 소스 코드 docdb_rest폴더에 있는 람다 소스 코드, 특히 app.py및 auth.py입니다.
1.템플릿과 코드를 사용하여 저장소를 복제합니다.
git clone https://github.com/aws-samples/docdb-rest.git
2. Amazon DocumentDB에 연결하려면 데이터베이스 드라이버 및 인증 기관 파일을 보유하는 Lambda 계층에 대한 .zip 파일을 빌드해야 합니다. 이렇게 하려면 다음 명령을 실행하십시오.
make
3. 이제 sam 명령을 통해 서버리스 애플리케이션을 빌드할 준비가 되었습니다.
sam build
4. 완료되면 서버리스 애플리케이션을 배포합니다.
sam deploy –capabilities CAPABILITY_NAMED_IAM –guided
5. 명령 줄에서 몇 가지 질문에 답해야 합니다.
-
-
-
- 스택 이름
- 배포 할 지역
- 이 스택에 의해 생성 된 리소스 앞에 추가 할 접두사 (콘솔에서 쉽게 식별하기 위해)
- Amazon DocumentDB 클러스터의 식별자
- Amazon DocumentDB 클러스터에 액세스하기 위한 사용자 이름
- Amazon DocumentDB 클러스터에 액세스하기 위한 암호
- Amazon DocumentDB 클러스터에 대한 네트워킹 액세스 권한이 있는 VPC 서브넷
- Amazon DocumentDB 클러스터에 대한 액세스 권한이 있는 보안 그룹
- REST API를 보호하는 데 사용할 사용자 이름
- REST API를 보호하는 데 사용할 비밀번호
-
-
6. 선택적으로 배포하기 전에 변경 사항을 확인하도록 선택합니다.
7. AWS SAM CLI가 IAM 역할을 생성하도록 허용해야 합니다.
8. 필요에 따라 구성 파일에 인수를 저장하고 구성 파일 이름과 구성 환경을 선택합니다.
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for ‘sam deploy’
=========================================
Stack Name [sam-app]: docdb-rest
AWS Region [us-east-1]: us-east-2
Parameter Prefix []: docdbrest
Parameter DocDBIdentifier []: docdb-cluster
Parameter DocDBUsername []: dbuser
Parameter DocDBPassword:
Parameter DocDBVPCSubnet []: subnet- XXXXXXXXXXXXXXXXX
Parameter DocDBSecurityGroup []: sg-XXXXXXXXXXXXXXXXX
Parameter APIUsername []: apiuser
Parameter APIPassword:
#Shows you resources changes to be deployed and require a ‘Y’ to initiate deploy
Confirm changes before deploy [Y/n]: Y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: Y
Save arguments to configuration file [Y/n]: Y
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
9. 메시지가 표시되면 이 변경 세트를 배포하도록 선택합니다.
10. 스택 배포가 완료되면 리소스 목록과 알림이 표시됩니다.
Successfully created/updated stack – docdb-rest in us-east-2
11. 배포 성공 시 표시 된 APIRoot출력을 기록해 둡니다. 이를 사용하여 다음 단계에서 API를 테스트합니다.
API 테스트
이제 curl을 통해 REST 엔드포인트를 호출하여 API를 테스트 할 수 있습니다. 이렇게 하려면 APIRoot배포 의 출력 인 URL을 가져와야 합니다. API Gateway에서이 정보를 검색 할 수도 있습니다.
1.API에 대한 루트 URL과 API에 액세스하기 위한 사용자 이름 및 비밀번호를 포함하도록 환경 변수를 설정해 보겠습니다.
export URLBASE=<the API URL from the console>
export APIUSER=<the API username>
export APIPWD=<the API password>
이제 몇 가지 HTTP 명령을 실행할 수 있습니다.
2. PUT를 통해 일부 데이터를 삽입하세요.
curl -X PUT -H “Content-Type: application/json” -d ‘{“name”:”brian”, “rating”: 5}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
curl -X PUT -H “Content-Type: application/json” -d ‘{“name”:”joe”, “rating”: 5}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
3. POST를 통해 일부 데이터를 삽입하세요.
curl -X POST -H “Content-Type: application/json” -d ‘{“name”:”jason”, “rating”: 3}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
4. GET을 통해 모든 데이터를 검색하세요.
curl -G https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
5. GET을 통해 joe 문서만 검색합니다.
curl -G –data-urlencode ‘filter={“name”: “joe”}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
6. joe 문서만 검색하지만 GET을 통해 이름 필드만 프로젝트합니다.
curl -G –data-urlencode ‘filter={“name”: “joe”}’ –data-urlencode ‘projection={“_id”: 0, “name”: 1}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
7. PATCH를 통해 jason 문서를 업데이트합니다.
curl -X PATCH -H “Content-Type: application/json” -d ‘{“filter”: {“name”: “jason”},”update”: {“$set”: {“rating”: 4}}}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
8. DELETE를 통해 jason 문서를 삭제합니다.
curl -X DELETE -H “Content-Type: application/json” -d ‘{“filter”: {“name”: “jason”}}’ https://$APIUSER:$APIPWD@$URLBASE/docdb/blog/test
Lambda 함수에 구현된 REST API 구문에 대한 자세한 내용은 리포지토리의 README 파일을 참조하세요.
특정 컬렉션에 대한 액세스 제한
이러한 명령은 URL에서 데이터베이스 및 컬렉션을 해석하는 일반 엔드포인트에 대해 실행되었습니다. 구현된 API에는 고정 데이터베이스 (demodb) 를 지정하지만 해당 데이터베이스의 모든 컬렉션에 대한 액세스를 허용하는 엔드포인트와 특정 데이터베이스 (demodb) 의 특정 컬렉션 (democollection) 을 지정하는 엔드포인트가 있습니다. 특정 컬렉션에 대한 엔드포인트만 노출되면 해당 컬렉션만 REST 명령을 통해 액세스할 수 있습니다. 이를 통해 필요에 따라 데이터베이스 및 컬렉션에 대한 광범위하거나 좁은 액세스 권한을 부여할 수 있습니다.
정리
AWS CloudFormation 콘솔 또는 AWS Command Line Interface (AWS CLI) 를 통해 스택을 삭제하여 이 게시물에서 생성된 리소스를 삭제할 수 있습니다. Amazon DocumentDB 클러스터는 이 작업으로 삭제되지 않습니다.
결론
지금까지 Amazon DocumentDB 데이터베이스의 컬렉션에 대한 읽기 및 쓰기 액세스 권한을 얻기 위해 REST API를 생성하는 방법을 시연했습니다. Amazon DocumentDB 액세스는 Amazon VPC 내에서만 가능하지만 VPC 외부에서 이 REST API에 액세스할 수 있습니다. 또한 API Gateway REST API와 Amazon DocumentDB 데이터베이스 사이의 다리 역할을 하고 삽입, 업데이트, 삭제 및 읽기 작업을 지원하는 단일 Lambda 함수를 생성하는 방법도 보여주었습니다. 마지막으로 Lambda 계층을 사용하여 Lambda 함수 개발을 단순화하는 방법과 Lambda 함수에서 사용할 수 있도록 Secrets Manager에 데이터베이스 자격 증명을 안전하게 저장하는 방법을 보여주었습니다.
최근 출시 및 블로그 게시물에 대한 자세한 내용은 Amazon DocumentDB (MongoDB 호환성 포함) 리소스를 참고하세요.
메가존 클라우드 TechBlog는 AWS BLOG 영문 게재 글 중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역 및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS 페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.