Amazon Web Services 한국 블로그

Amazon API Gateway 기반 HTTP API 정식 출시 (서울 리전 포함)

2015 년 7 월 AWS는 Amazon API Gateway를 발표하여, 다양한 유형의 아키텍처 앞에서 안전하고 확장 가능한 API를 신속하게 구축 할 수 있었습니다. 그 이후로 API Gateway 팀은 고객을 위한 새로운 기능과 서비스를 계속 구축해 왔습니다.

그림 1 : 타임 라인을 강조하는 API Gateway 기능

2019 년 초 API 게이트웨이 서비스에 대한 고객 피드백을 기반으로  새로운 언어와 기술을 프로토 타입화하고 REST 및 WebSocket API를 구축하였습니다. 그 결과 지난  AWS re:Invent 2019에서 더욱 빠르고 낮은 비용으로도 사용하기 쉬운 서비스 인 Amazon API Gateway 기반 HTTP API  미리 보기를 출시했으며, 오늘 정식 출시 합니다.

Amazon API Gateway 기반 HTTP API의 주요 기능

대부분의 경우에서 HTTP API는 대기 시간을 최대 60 %까지 줄입니다. 개발자는 최소 대기 시간과 최대 기능으로 애플리케이션을 구축하려고 노력하고 있습니다.

모든 서비스는 대기 시간을 추가

그림 2 : 모든 서비스가 대기 시간을 추가

이를 염두에 두고 HTTP API는 API Gateway 서비스의 대기 시간 오버 헤드를 줄이기 위해 요청과 응답을 결합하여 모든 요청의 99 % (p99)는 HTTP API에서 10ms 미만의 추가 대기 시간을 갖습니다.

특히, 비용 효율적인 방식으로 작업를 수행하고 높은 가용성을 확보하기 위해 API Gateway를 운영한 경험을 바탕으로  HTTP API를 구축했습니다.

REST / HTTP API 가격 비교

그림 3 : REST / HTTP API 가격 비교

us-east-1 의 요금 내역을 기반으로 한 달에 1 억, 5 억 및 10 억 요청에 대한 비용 비교를 살펴 보았을 때, 전반적으로 HTTP API는 API Gateway REST API에 비해 최소 71 % 저렴합니다.

또한, HTTP API 사용자 인터페이스에서 기존 보다 직관적이고 사용하기 쉽게 만들었습니다. 예를 들어, CORS (Cross Origin Resource Scripting) 구성의 경우,  각 서버에 대한 도메인 간 액세스를 제어하여 보안을 제공하며 이해 및 구성이 어려울 수 있습니다.

HTTP API를 사용하면 개발자가 이해하기 쉬운 단순 UI를 사용하여 CORS 설정을 빠르게 구성 할 수 있습니다. UI 전체에서 이와 동일한 접근 방식을 사용하면 API를 작성하는 강력하면서도 쉬운 접근 방식이 만들어집니다.

CORS 구성

그림 4 : CORS 구성

HTTP API의 신규 기능

지난 미리 보기 출시에서 JWT 권한 부 여자, 자동 배포 단계 및 간단한 경로 통합과 같은 강력한 기능을 발표하였고, 고객의 피드백을 통해 몇 가지 추가 기능을 출시합니다.

VPC 통합
HTTP API는 개발자에게 Amazon VPC에서 보호된 리소스와 통합 할 수 있는 기능을 제공합니다. Amazon ECS (Amazon Elastic Container Service) 또는 Amazon EKS (Amazon Elastic Kubernetes Service ) 를 통한 컨테이너와 같은 기술로 개발할 때는 기본 Amazon EC2 클러스터가 VPC 내에 있어야 합니다. Elastic Load Balancing을 통해 이러한 서비스를 제공 할 수 있지만 개발자는 HTTP API를 활용하여 애플리케이션을 지원할 수도 있습니다.

VPC 링크 구성

그림 5 : VPC 링크 구성

프라이빗 네트워크 통합을 하려면 VPC 링크 가 필요합니다 . VPC 링크는 Network Load Balancer 및 NAT 게이트웨이에 사용되는 네트워크 기능 가상화 플랫폼 인 AWS Hyperplane 을 활용 합니다. 이 기술을 사용하면 여러 HTTP API가 VPC에 대한 단일 VPC 링크를 사용할 수 있습니다. 마찬가지로 여러 REST API가 REST API VPC 링크를 사용할 수 있습니다.

개인 통합 구성

그림 6 : 개인 통합 구성

VPC 링크가 존재하면 NLB (Network Load Balancer), ALB (Application Load Balancer) 또는 리소스 검색 서비스 인 AWS Cloud Map을 사용하여 HTTP API 프라이빗 통합을 구성 할 수 있습니다 .

맞춤형 도메인 상호 호환성
Amazon API Gateway는 이제 REST API 및 HTTP API에서 사용자 정의 도메인을 공유 할 수있는 기능을 제공합니다. 이러한 유연성 덕분에 개발자는 애플리케이션을 구축하는 동안 REST API와 HTTP API를 혼합하여 사용할 수 있습니다.

맞춤 도메인 상호 호환성

그림 7 : 사용자 정의 도메인 상호 호환성

이전에는 하나의 도메인 이름이 필요한 애플리케이션을 구축 할 때 개발자는 단일 유형의 API 만 사용할 수 있었습니다. 어떤 애플리케이션은 REST에서만 사용 가능한 기능이 필요하기 때문에 REST API를 선택할 수 밖에 없으나, 오늘부터 기능 요구 사항에 따라 HTTP API와 REST API간에 이러한 경로를 상호 배포 할 수 있습니다.

스로틀링(Throttling) 요청
HTTP API는 각 단계 및 경로 수준에서 세부 트래픽 조절을 수행 할 수 있는 기능을 제공합니다. API 스로틀링은 API 및 해당 인프라의 상태에 자주 간과되는 API 기능입니다. 기본적으로 API Gateway 는 정상 요청 속도를 5,000 요청 버스트 제한으로 초당 10,000 요청 (rps)으로 제한합니다. 이는 소프트 한도이며 AWS 서비스 할당량을 통해 올릴 수 있습니다 .

HTTP API에는 다양한 목적으로 사용할 수 있는 단계(Stage) 개념이 있습니다. 애플리케이션은 동일한 API에서 개발, 베타 및 제품 단계를 가질 수 있습니다. 또한 이전 버전과의 호환성을 위해 동일한 API의 여러 프로덕션 단계를 구성 할 수 있습니다. 각 단계에는 계정 레벨 설정을 10,000rps보다 우선하는 버스트 및 속도 제한 설정 옵션이 있습니다.

스테이지 레벨 조절

그림 8 : 스테이지 레벨 조절

경로 수준에서 제한을 설정할 수도 있습니다. 경로는 경로와 방법의 조합입니다. 예를 들어 루트 경로 (/)의 GET 메소드는 결합하여 경로를 만듭니다. 이 글을 쓰는 시점에서 AWS Command Line Interface (CLI) 또는 AWS SDK를 사용하여 경로 수준 조절을 만들어야합니다 . $ default 스테이지 에서 / [ANY] 라우트에 제한을 설정하려면 다음 CLI 명령을 사용하시기 바랍니다.

aws apigatewayv2 update-stage --api-id <your API ID> --stage-name $default --route-settings '{"ANY /": {"ThrottlingBurstLimit":1000, "ThrottlingRateLimit":2000}}'

단계 변수(Stage Variables)
HTTP API는 동적 변수를 백엔드 통합으로 전달하거나 통합 자체를 정의하기 위해 스테이지 변수 사용을 지원합니다. 스테이지가 HTTP API에 정의되면 백엔드 통합에 대한 새로운 경로가 작성됩니다. 다음 표는 여러 단계가있는 도메인을 보여줍니다.

단계 통로
$ default www.mydomain.com
dev www.mydomain.com/dev
베타 www.mydomain.com/beta

dev 스테이지의 링크에  접근하면 dev 스테이지 변수가 이벤트 오브젝트 백엔드 통합으로 전달됩니다 . 백엔드는 요청을 처리 할 때, 이 정보를 사용합니다. 개인 정보 같은 민감한 정보를 전달하는 가장 좋은 방법은 아니지만, 환경 별 엔드 포인트 또는 기능 스위치와 같은 민감하지 않은 데이터를 지정하는 데 유용합니다.

백엔드 통합을 동적으로 정의하는 데 스테이지 변수도 사용됩니다. 예를 들어, 통합 에서 프로덕션을 위해 하나의 AWS Lambda 함수를 사용하고 테스트를 위해 다른 하나를 사용하는 경우 스테이지 변수를 사용하여 아래와 같이 적절한 Lambda 함수로 동적으로 라우팅 할 수 있습니다.

통합 지점을 동적으로 선택

그림 9 : 통합 지점을 동적으로 선택

동적 통합(Dynamic Integration)을 구축 할 때, 그에 따른 권한을 업데이트하는 것도 중요합니다. 통합이 단일 Lambda 함수를 가리킬 때 HTTP API는 자동으로 호출 권한을 추가합니다. 그러나 여러 기능을 사용하는 경우 역할을 수동으로 작성하고 관리해야합니다. Lambda 함수를 호출하기위한 API 게이트웨이 권한 부여 옵션을 해제하고 적절한 권한으로 사용자 정의 역할을 입력하여 이를 수행하시기 바랍니다.

통합 사용자 정의 역할

그림 10 : 통합 사용자 정의 역할

Lambda 페이로드 버전 2.0
HTTP API는 Lambda 함수 통합을 위해 업데이트 된 이벤트 페이로드 및 응답 형식을 지원합니다. 버전 2.0 페이로드는 Lambda 함수로 전송되는 이벤트 객체의 형식을 단순화합니다. 다음은 버전 1.0 및 2.0에서 Lambda 함수로 전송되는 이벤트 객체를 비교 한 것입니다.

버전 1.0

{
    "version": "1.0",
    "resource": "/Echo",
    "path": "/Echo",
    "httpMethod": "GET",
    "headers": {
        "Content-Length": "0",
        "Host": "0000000000.execute-api.us-east-1.amazonaws.com",
        "User-Agent": "TestClient",
        "X-Amzn-Trace-Id": "Root=1-5e6ab926-933e1530e55773a0709dfaa6",
        "X-Forwarded-For": "1.1.1.1",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https",
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "cache-control": "no-cache",
        "clientInformation": "private",
        "cookie": "Cookie_2=value; Cookie_3=value; Cookie_4=value"
    },
    "multiValueHeaders": {
        "Content-Length": [
            "0"
        ],
        "Host": [
            "0000000000.execute-api.us-east-1.amazonaws.com"
        ],
        "X-Amzn-Trace-Id": [
            "Root=1-5e6ab926-933e1530e55773a0709dfaa6"
        ],
        "X-Forwarded-For": [
            "1.1.1.1"
        ],
        "X-Forwarded-Port": [
            "443"
        ],
        "X-Forwarded-Proto": [
            "https"
        ],
        "accept": [
            "*/*"
        ],
        "accept-encoding": [
            "gzip, deflate, br"
        ],
        "cache-control": [
            "no-cache"
        ],
        "clientInformation": [
            "public",
            "private"
        ],
        "cookie": [
            "Cookie_2=value; Cookie_3=value; Cookie_4=value"
        ]
    },
    "queryStringParameters": {
        "getValueFor": "newClient"
    },
    "multiValueQueryStringParameters": {
        "getValueFor": [
            "newClient"
        ]
    },
    "requestContext": {
        "accountId": "0000000000",
        "apiId": "0000000000",
        "domainName": "0000000000.execute-api.us-east-1.amazonaws.com",
        "domainPrefix": "0000000000",
        "extendedRequestId": "JTHd9j2EoAMEPEA=",
        "httpMethod": "GET",
        "identity": {
            "accessKey": null,
            "accountId": null,
            "caller": null,
            "cognitoAuthenticationProvider": null,
            "cognitoAuthenticationType": null,
            "cognitoIdentityId": null,
            "cognitoIdentityPoolId": null,
            "principalOrgId": null,
            "sourceIp": "1.1.1.1",
            "user": null,
            "userAgent": "TestClient",
            "userArn": null
        },
        "path": "/Echo",
        "protocol": "HTTP/1.1",
        "requestId": "JTHd9j2EoAMEPEA=",
        "requestTime": "12/Mar/2020:22:35:18 +0000",
        "requestTimeEpoch": 1584052518094,
        "resourceId": null,
        "resourcePath": "/Echo",
        "stage": "$default"
    },
    "pathParameters": null,
    "stageVariables": null,
    "body": null,
    "isBase64Encoded": true
}

버전 2.0

{
    "version": "2.0",
    "routeKey": "ANY /Echo",
    "rawPath": "/Echo",
    "rawQueryString": "getValueFor=newClient",
    "cookies": [
        "Cookie_2=value",
        "Cookie_3=value",
        "Cookie_4=value"
    ],
    "headers": {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "cache-control": "no-cache",
        "clientinformation": "public,private",
        "content-length": "0",
        "host": "0000000000.execute-api.us-east-1.amazonaws.com",
        "user-agent": "TestClient",
        "x-amzn-trace-id": "Root=1-5e6ab967-cfe253ce6f8b90986a678c40",
        "x-forwarded-for": "1.1.1.1",
        "x-forwarded-port": "443",
        "x-forwarded-proto": "https"
    },
    "queryStringParameters": {
        "getValueFor": "newClient"
    },
    "requestContext": {
        "accountId": "0000000000",
        "apiId": "0000000000",
        "domainName": "0000000000.execute-api.us-east-1.amazonaws.com",
        "domainPrefix": "0000000000",
        "http": {
            "method": "GET",
            "path": "/Echo",
            "protocol": "HTTP/1.1",
            "sourceIp": "1.1.1.1",
            "userAgent": "TestClient"
        },
        "requestId": "JTHoQgr2oAMEPMg=",
        "routeId": "47matwk",
        "routeKey": "ANY /Echo",
        "stage": "$default",
        "time": "12/Mar/2020:22:36:23 +0000",
        "timeEpoch": 1584052583903
    },
    "isBase64Encoded": true
}

또한 버전 2.0을 사용하면 Lambda 함수의 응답 객체 형식이 더 유연 해집니다. 이전에는 응답의 필수 형식이었습니다.

{
  “statusCode”: 200,
  “body”:
  {
    “Name”: “Eric Johnson”,
    “TwitterHandle”: “@edjgeek”
  },
  Headers: {
    “Access-Control-Allow-Origin”: “https://amazon.com”
  }
}

버전 2.0을 사용할 때 응답이 더 간단합니다.

{
  “Name”: “Eric Johnson”,
  “TwitterHandle”: “@edjgeek”
}

HTTP API가 응답을 수신하면 CORS 설정 및 통합 응답 코드와 같은 데이터를 사용하여 누락 된 데이터를 채우게 됩니다.

기본적으로 새로운 Lambda 함수 통합은 버전 2.0을 사용합니다. Lambda 함수 통합에 대한 고급 설정 토글에서 이를 변경할 수 있습니다 . 이 버전은 이벤트 및 응답 페이로드 모두에 적용됩니다. 버전 1.0을 선택하면 이전 이벤트 형식이 Lambda 함수로 전송되고 전체 응답 오브젝트가 리턴되어야합니다.

Lambda 통합 고급 설정

그림 11 : Lambda 통합 고급 설정

OpenAPI / Swagger 지원
HTTP API는 이제 Swagger 또는 OpenAPI 구성 파일 가져 오기를 지원 합니다. 따라서 다른 API 게이트웨이 서비스에서 HTTP API로 간단하게 마이그레이션 할 수 있습니다. 구성 파일을 가져올 때 HTTP API는 지원되는 모든 기능을 구현하고 현재 지원되지 않는 기능을 보고합니다.

AWS Serverless Application Model (SAM) 지원
AWS Serverless Application Framework (SAM) 는 re:Invent 2019에서 베타로 출시한 대부분의 기능을 지원합니다. 오늘 출시된 기능에 대한 AWS SAM 지원은 2020 년 3 월 20 일에 출시될 예정입니다.

더 자세한 것은 제품 페이지기술 문서를 참고하시기 바랍니다.

– Eric Johnson, AWS Serverless Developer Advocate

이 글은 AWS Compute 블로그의 Building faster, lower cost, better APIs – HTTP APIs now generally available 한국어 편집본입니다.