gony-dev 님의 블로그

Section 23. AWS Serverless: API Gateway 본문

AWS

Section 23. AWS Serverless: API Gateway

minarinamu 2024. 11. 15. 00:10

API Gateway

클라이언트가 람다 함수를 직접 호출하기 위해서는 IAM 권한이 있어야 한다.
ALB를 사용하여 클라이언트와 람다 함수 사이에 권한을 둘 수가 있는데, 그러면 람다 함수가 HTTP 엔드포인트로 노출된다.
API Gateway는 AWS에서 제공하는 서버리스 서비스로 클라이언트가 액세스 할 수 있게 공개적인 REST API를 만들 수 있다!
클라이언트가 API 게이트웨이에 통신하면 람다 함수로 요청을 프록시한다.
  • 람다와 API 게이트웨이의 조합은 관리할 인프라가 없는 완전한 서버리스 어플리케이션이 된다.
  • 웹소켓 프로토콜이 지원이 되어 API 게이트웨이를 통해 실시간 스트리밍이 가능하다.
  • API 게이트웨이는 버저닝을 처리하므로 버전1에서 버전2, 3으로 변경도 할 수 있다.
  • 다양한 환경을 처리할 수도 있으며 보안 측면에서 인증과 권한 부여 목적으로 적용할 수 있는 보안이 많다.
  • API 키를 생성해 클라이언트가 API 게이트웨이에 너무 많은 요청을 보낸다면 스로틀링을 요청할 수도 있다.
  • 요청과 응답을 변환 및 무효화할 수 있다.
  • SDK나 API 규격을 생성하고, API 응답을 캐싱할 수도 있다.

Endpoint Types

API 게이트웨이의 배포 방식(=엔드포인트 유형)은 3가지가 있다.

  • Edge-Optimized(default)
    • 글로벌 클라이언트에 이용된다.
    • 모든 CloudFront Edge 위치를 통해 요청을 라우팅하므로 지연 시간을 개선
    • API 게이트웨이는 생성했던 한 리전에만 남는다.
  • Regional
    • CloudFront Edge 위치를 사용하지 않을 때 사용한다.
    • 모든 사용자가 API 게이트웨이를 만든 리전 내에 위치할 것으로 예상할 때 사용한다.
    • 원할시 CloudFront 배포를 자체적으로 만들 수 있는데 그렇게 되면 Edge-Optimized 배포와 같아진다.
  • Private
    • VPC 내에서만 액세스가 가능하고 인터페이스 VPC 엔드포인트를 사용한다.
    • API 게이트웨이 액세스를 정의하는데 리소스 정책을 사용할 수 있다.

Security

  • 사용자 식별에 필요한 보안
    • IAM Roles
    • Cognito(외부 유저들에 대한 신원)
    • 커스텀 권한
  • AWS Certificate Manager(ACM)과 통합한 커스텀 도메인 네임 HTTPS 보안
    • Edge-Optimized 엔드포인트를 사용한다면, 인증서는 us-east-1에 있어야만 한다.
    • Regional endpoint를 사용한다면, 인증서는 API 게이트웨이 리전 내에 있어야만 한다.
    • 반드시 Route53에 CNAME이나 A-alias 레코드를 설정하여 API 게이트웨이를 연결해야 한다!

Deployment Stages

  • 매번 API 게이트웨이를 변경하더라도 배포하기 전까지는 유효하지 않았다.
  • 작동하려면 배포를 수행해야 하는데, 이것은 상당히 혼란스러울 수 있다..
  • 변경 사항은 "Stage"에만 배포되며, 스테이지 수는 원하는 대로 정할 수 있고 필요하다면 이름을 붙일 수 있다.(ex. dev, test)
  • 각 스테이지는 고유한 구성 매개변수를 갖고, 원활히 롤백할 수 있다. 왜냐하면 스테이지에서 수행된 모든 배포 전체 이력이 보관되기 때문이다.

Stage Variables(스테이지 변수)

  • 스테이지 변수는 환경 변수와 비슷하지만 API 게이트웨이 스테이지로 사용된다.
  • ${stageVariables.lambdaAlias}를 사용!
  • API를 다시 배포하지 않고도 구성 값을 변경할 수 있는데, 사용 예시를 보자.
    • 람다 한수 ARN
    • HTTP Endpoint
    • 파라미터 매핑 템플릿
  • 사용 사례
    • HTTP 엔드포인트를 스테이지에서 구성할 때 사용
    • 매핑 템플릿으로 람다 함수에 구성 매개변수를 전달하거나 올바른 람다 함수를 가리킬 때 사용한다.

각 버전의 비율을 업데이트하여 람다 별칭을 변경할 수 있다.


API Gateway - Canary Deployment

  • Canary 배포는 변경 사항에 관해 소량의 트래픽으로 테스트하는 방법을 활성화하는 방법이다.
  • 이 방법은 canary 채널을 받는 트래픽의 비율을 선택해야 하며 이를 통해 API Gateway에 새 버전을 테스트할 수 있다.
  • 더 나은 모니터링을 위해 지표 및 로그를 분리하고 있다.
  • canary 단계에서 원하는 단계의 변수를 재정의할 수 있는데, 이는 AWS 람다와 API Gateway에서 블루/그린 배포를 실행하는 것과 같다.

소량의 트래픽을 Canary에 배분하다가 정상적으로 실행되면 100%로 배포한다.


Integration Types

1. Integration Type MOCK

  • 백엔드로 요청을 보내지 않고도 응답을 반환하는 유형
  • 개발하고 테스트하기 위한 용도로 쓰인다.

2. Integration Type HTTP/AWS (Lambda & AWS Services)

  • 사용자는 통합 요청과 통합 응답 모두 구성해야 한다.
  • 구성할 때는 요청 및 응답 매핑 템플릿을 사용하여 데이터 매핑을 구성할 수 있다.
  • 백엔드로 향하는 요청을 변경하고, 클라이언트에게 전송하기 전에 백엔드에서 응답을 변경할 수 있다.

3. Integration Type AWS_PROXY (Lambda Proxy)

  • 클라이언트로부터 오는 요청은 람다에 대한 입력이 된다.
  • 요청과 응답 논리에 함수만이 작용한다.
  • 매핑 템플릿을 사용할 수 없다. 단, 모두 함수의 인자로 바로 전달된다.

4. Integration Type HTTP_PROXY

  • 프록시이기에 매핑 템플릿이 없고 요청이 직접 전달된다.
  • 백엔드로 프록시하여 응답을 하면 API 게이트웨이가 응답을 클라이언트에게로 다시 프록시 한다.
  • 원한다면 HTTP 헤더를 추가할 수 있다.

Mapping Templates

  • 요청과 응답을 수정하는 매핑 템플릿은 프록시 방식을 사용하지 않고 AWS 서비스나 HTTP로 통합할 때만 적용되며, 요청과 응답을 수정하는데 사용할 수 있다.
  • 매핑 템플릿으로 쿼리 문자열 매개벼수의 이름을 바꾸거나 본문 컨텐츠를 수정하거나, 헤더를 추가할 수도 있다.
  • Velocity Template Language(VTL)로 반복문, 조건문을 수행할 수 있다.

Mapping Example: JSON to XML with SOAP(시험 유의)

  • SOAP API은 XML에 바탕이 되지만, REST API는 JSON에 기반한다.

  • 클라이언트에서 받은 JSON 형식을 API 게이트웨이가 매핑 템플릿으로 XML 페이로드를 통해 해당 페이로드를 SOAP API로 바꾸고 응답을 받아 다시 원하는 형태로 클라이언트에 전달한다.

Open API spec

  • Open API는 REST API는 정의하는 흔한 방식으로, 코드로 API를 정의한다.
  • API 게이트웨이로 Open API 3.0 스펙을 임포트한다.
    • 이는 메서드, 메서드 요청, 통합 요청, 메서드 응답을 정의한다.
  • 또한 Open API 스펙으로서 기존 API를 익스포트할 수 있다.

Rest API - Request Validation

  • 통합 요청으로 진행하기 전에 API 요청의 기본적인 확인을 수행하기 위해 API 게이트웨이를 구성할 수 있다.
  • 확인이 실패할 때, API 게이트웨이는 즉시 요청을 실패처리한다.
  • 실패처리를 함으로 백엔드에 불필요한 호출을 줄일 수 있다!

OpenAPI 요청 확인

  • 요청 확인을 진행하기 위해선 Open API 정의 파일을 설정하고, "x-amazon-apigateway-request-validators"를 정의한다.
    • 모든 API 메서드에 대해 파라미터를 검증할 수도 있고, 모든 검증자를 적용할 수도 있다.

Caching API responses

캐싱 | 백엔드에 대한 호출 수를 줄이는 행위
캐시가 없다면 백엔드와 통신하여 결과를 얻는다.

기본적으로 결과가 캐시에 유지되는 시간은 300초이다.
최소 시간은 0초이며, 최대는 1시간까지 가능하다.
캐시는 단계당 하나의 캐시를 정의하게 되고, 메서드별로 캐시 설정을 재정의할 수 있다.
캐시 크기는 0.5GB에서 237GB까지 저장할 수 있다.

캐싱은 운영이나 사전 운영 환경에서 사용해야하는 것을 추천!!

API Gateway Cache Invalidation

  • 캐시를 무효화하기 위해서는 어떻게 하면 좋을까?
  • 클라이언트에서 API 게이트웨이로 보내는 쿼리에 "Cache-Control: max-age=0"이라는 헤더를 넣어 캐시를 무효화할 수 있다.
    • 이를 수행하려면 적절한 IAM 인증이 필요하다.

캐시를 무효화하는 헤더를 IAM 정책에 작성할 수 있다!

  • 람다를 통해 테스트하였을 때, 매번 람다에게 결과를 가져오라고 요청하는 대신 API 게이트웨이가 캐시를 가져온다.

한 번 API를 요청한 후부터는 캐시를 사용해서 결과를 불러온다.


Usage Plans & API Keys

API 키를 만들었으면 고객들에게 배포를 하고 비용을 받는 게 당연하다.

이를 위해 사용량 계획과 API 키를 배워보자!

  • Usage Plan
    • 누가 하나 이상의 배포된 API 스테이지와 메서드에 접근할 수 있는지 
    • 어떤 API 키가 고객을 식별하고 접근을 계산하기 위해 이 사용량 계획에 연결될 지에 관한 사용량 계획을 생성해야 한다.
    • 조절 한도를 구성해서 얼마나 빨리 API를 대상으로 할 수 있는지 설정하며 할당량도 구성한다.
  • API Keys
    • 고객에게 나누어주는 문자열로 되어 있다.
    • 고객들이 안전하게 API 게이트웨이를 사용하고 요청을 인증할 수 있게 만들어 준다!
    • 또한 사용량 계획과 같이 사용해서 접근을 제어할 수 있다.
    • 제어량은 API 키에 적용된다.
    • 할당량은 요청의 전체적인 수로 사용량 계획과 API 키를 이용해서 모니터링할 수 있다!

Correct Order for API Keys

  • 사용량 계획 구성 방식
    1. 하나 이상의 API 키를 만들고, API 키를 필요로 하는 메서드와 API를 스테이지에 배포한다.
    2. API 키를 생성 또는 받아오는데 이는 API를 사용할 어플리케이션 고객들에게 분배하기 위함이다.
    3. 원하는 조절 한도와 할당량으로 사용량 계획을 생성한다.
    4. API 스테이지들과 키들을 사용량 계획과 연결 짓는다.

Logging & Tracing

  • 로깅하고 추적하는 방법을 알아보자
  • 1. CloudWatch Logs
    • 로그는 요청 및 응답 body에 대해 정보를 포함하고 있다.
    • CloudWatch Logs는 스테이지 레벨에서 사용 설정을 할 수 있다.(Log level - ERROR, DEBUG, INFO)
  • 2. X-Ray
    • X-Ray는 API 게이트웨이에서 요청에 대해 추가 정보를 얻기위해 추적한다.
    • "X-Ray API 게이트웨이 + AWS 람다" 조합은 전체적인 과정을 보여준다.

사용자가 요청 또는 응답하는 과정에서 자동으로 CloudWatch Logs에 로그가 남게 된다.

1.  CloudWatch Metrics

  • API 게이트웨이를 CloudWatch Metrics로 단계별로 모니터링할 수도 있고, 상세 지표도 사용 설정이 가능하다.
  • 자격증 시험에 나올지도 모르는 Metrics 유형들을 알아보자.

1. CacheHitCount & CacheMissCount | 캐시 효율에 관한 정보를 제공한다.

2. Count | 주어진 기간의 API 요청 수이다.

3. IntegrationLatency | API 게이트웨이가 백엔드에 요청을 전달할 때와 응답을 받을 때 사이의 시간을 측정한다.(=백엔드가 API Gateway로 응답하는데 걸리는 시간)

4. Latency | API 게이트웨이가 클라이언트로부터 요청을 받아서 다시 응답을 반환할 때까지의 시간이다. 지연 시간은 통합 지연 시간과 다른 API 게이트웨이의 모든 작업도 포함된다.

5. 4XX Error & 5XX Error | 클라이언트 측 에러와 백엔드 측 에러

 

주의 | API 게이트웨이가 요청을 수행할 수 있는 최대 시간은 29초이다!

이는 Latency나 IntegrationLatency가 29초를 넘으면 API 게이트웨이에서 시간 초과를 발행한다는 의미이다.

 

2. API Gateway Throttling

  • API 게이트웨이는 사용 계획 등을 이용해 조절할 수 있는데, 계정 제한도 정의할 수 있다!

1. Account Limit

  • API 게이트웨이는 모든 API에 걸쳐 10,000건으로 요청을 조절한다.
  • 요청에 따라 더 늘어날 수 있으며, 이는 API 중 하나가 과하게 사용된다면 다른 API도 조절할 수 있다는 의미이다.

2. 수행 능력을 향상시키기 위해서는 스테이지 limit과 메서드 limit을 설정할 수 있다.

3. 아니면 고객 당 조절하는 것을 원한다면 사용 계획을 정의할 수도 있다.


API Gateway - CORS & Authentication

1. CORS

  • CORS는 사용자가 다른 도메인에서 API 호출을 받는 것을 가능하게 한다.
  • 이 API 게이트웨이가 동작하기 위해서는 사전 전달 요청이라는 옵션을 만들어야하는데 헤더는 다음과 같다.
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Allow-Origin

교차 오리진 유형의 요청을 하는 과정이다.

2. Authentication

1. Security IAM Permissions

  • IAM 정책 권한을 생성하여 사용자와 역할에 연결하면 API 게이트웨이에 연결할 수 있다.
  • 인증은 IAM을 통해 이루어지고, 권한 부여는 IAM 정책을 통해 이루어짐을 잘 알자!
  • IAM 증명을 API 게이트웨이로 전달하려면 "Signature v4" 기능을 이용할 수 있는데, 이는 증명이 서명되고 헤더에 위치되게 한다.

2. Resource Policies

  • 리소스 정책은 API 게이트웨이에 JSON 형식의 정책을 설정할 수 있게 하여 누가 어떻게 API 게이트웨이에 접근할 수 있는지 정의한다.
  • 리소스 정책의 기본 사용 예시는 교차 계정 접근(Cross Acount Access)의 사용이다.
  • 리소스 정책을 사용하여 특정 소스의 IP 주소나 VPC 엔드포인트를 허용할 수 있다.

3. Security Cognito User Pools

  • Cognito는 요약하자면 사용자들의 데이터베이스이다. 사용자 라이프 사이클을 총 관리하고, 연결 토큰은 자동 만료가 되기 때문에 API 게이트웨이는 연결하려는 사람들의 신분을 Cognito로 식별한다.
  • 사용자는 Cognito User Pools에 의해 인증 받고, API 게이트웨이 메서드로의 권한을 부여 받는다.

Cognito에서 토큰을 받아 API 게이트웨이에 접근하여 토큰을 평가받고 람다를 이용한다!

4. Security Lambda Authorizer

  • 가장 유연하지만 많은 관심이 필요한 방법이다.
  • 토큰 기반 권한 부여자로 bearer token이 있는데, 이는 JWT나 Oauth와 비슷하다.
  • 헤더나 쿼리 문자열 등의 요청 기반의 파라미터들을 람다 권한 부여자로 전달한다.
  • 람다 함수는 전달 받은 것을 평가하고 이상이 없다면 요청을 만든 클라이언트를 위한 IAM 정책을 반환하고, 이 정책은 캐싱된다.
  • 사용자는 외부에서 인증을 받고, 람다 함수에서 권한을 부여받는다.

서드 파티에서 토큰을 받아 API 게이트웨이에서 람다를 통해 인증을 받고 백엔드와 통신한다!

Summary

  1. IAM
    • 계정에 이미 생성된 사용자와 역할이 있을 때 유용
    • 교차 계정 접근을 위해 리소스 정책을 사용해야 함.
    • Signature v4를 사용
  2. Custom Authorizer
    • 서드 파티 토큰을 사용할 때 유용
    • 어떤 IAM 반환할지에 대해 고르기 때문에 유연하다.
    • 직접 인증을 다루어야 하고, 람다 함수에서 권한 부여를 다루어야 한다.
    • 결과가 캐싱되었더라도 람다 호출시마다 요금이 발생하고 요금이 청구된다.
  3. Cognito User Pool
    • 직접 사용자 풀을 관리한다.
    • 커스텀 코드를 작성할 필요는 없다.

HTTP API vs. REST API

1. HTTP APIs

  • 지연 시간이 적고, 효율적인 비용으로 람다 proxy와 HTTP proxy, private한 통합을 의미한다.
  • 데이터 매핑이 제공되지 않는다.
  • 제한적인 인증으로 OIDC와 Oauth 2.0만 지원한다.
  • 사용 계획이나 API 키가 없다.

2. REST APIs

  • 지금까지 강의에서 배운 모든 특징들을 가지고 있다.(Native OpenID Connect와 OAuth 2.0은 예외!)

표로 설명한 두 API 유형의 차이

알아두면 좋은 차이는

  • HTTP API가 REST API보다 훨씬 저렴하며 지원측면에서 약간 다른 점을 갖는다.
  • REST API는 리소스 정책을 지원하지만 HTTP API는 그렇지 않다.

WebSocket API

WebSocket은 사용자 브라우저와 서버 사이에 양방향 상호작용이 있는 것이다.
양방향인 이유는 클라이언트가 요청하지 않아도 서버가 클라이언트에게 정보를 다시 보낼 수 있기 때문이다.
이는 상태 유지 어플리케이션에서 사용이 가능하다.
  • WebSocket API는 실시간 어플리케이션에서 주로 사용되며, 채팅 어플리케이션, 협업 플랫폼 등에서 사용된다.

메시지를 보내고 싶거나 연결을 끊고 싶을 때 원하는 대로 할 수 있다!

1. Connecting to the API

  • WebSocket URL은 wss로 시작한다. 이는 암호화된 형태이다.
    • wss://[some-uniqueid].execute-api.[region].amazonaws.com/[stage-name]
    • 고유 id에 위의 형태가 들어간다.

2. Client to Server Messaging ConnectionID is re-used

  • 클라이언트가 서버에 메시지를 보내고자 하면 과정은 다음과 같다.

3. Server to Clinet Messaging

  • 데이터를 다시 가지고 오는 것이 목적으로 연결 URL 콜백이 실행된다.
    • 연결 URL은 기존 URL에서 "/@connections/connectionid"가 들어간다.

4. Connection URL Operations

Operation Action
POST 서버에서 연결된 클라이언트로 메시지를 보낸다.
GET 연결된 클라이언트의 최신 연결 상태를 얻는다.
DELETE 클라이언트와의 연결을 해제한다.

5. WebSocket API - Routing

  • 오는 JSON 메시지는 다른 백엔드로 라우팅된다.
  • 만일 라우트를 따로 지정하지 않았다면, 기본 라우트로 이동한다.
  • 따라서 선택하거나 라우트 선택 표현식을 생성해서 라우팅할 JSON 필드를 선택할 수 있다.
  • action이랑 요소의 결과는 API 게이트웨이에서 이용할 수 있는 라우트 키 테이블을 평가한다.
    • join이란 라우트가 존재하면 본 API 게이트웨이는 해당 라우트가 특정 백엔드에 연결되어 있으며, API 게이트웨이와 통합되어 있는 람다 함수나 기타 함수를 이용할 수 있다는 것을 알게 된다.
    • 일치하는 라우트가 없다면, 기본 라우트로 전송된다.


API Gateway - Architecture

  • 우리는 회사에서 API 게이트웨이로 실행할 수 있는 모든 마이크로서비스를 단일 인터페이스에서 표시할 수 있다.
  • 다양한 리소스를 가지고 API 엔드포인트를 사용한다.

API Gateway Architecture 예시