REST API
REST APIは、API Gatewayの豊富なAPI管理機能を利用したい場合に向いています。
API Cache
Usage Plan
API Key
VTL Mapping Template
AWS WAF連携
HTTP API
HTTP APIはREST APIよりシンプルで、低コスト・低レイテンシを重視したAPIです。
シンプルなAPI
+
Lambda
→ HTTP API
のような構成に向いています。
HTTP APIではJWT Authorizerを利用できます。
Client
↓
JWT
↓
API Gateway
↓
JWT検証
↓
Backend
JWTの署名や、
iss
aud
exp
scope
などをAPI Gateway側で検証できます。
Cognitoが発行したJWTを利用する構成にも対応できます。
WebSocket API
リアルタイムの双方向通信が必要な場合は、WebSocket APIを利用できます。
チャット
リアルタイム通知
ゲーム
リアルタイムDashboard
Client
⇅
WebSocket API
⇅
Backend
REST APIやHTTP APIのようにClientからRequestを送るだけではなく、Server側からClientへデータを送信できます。
API GatewayのEndpoint Type
REST APIでは、APIをどこから利用するかによってEndpoint Typeを選択できます。
Edge-optimized
Regional
Private
Edge-optimized
世界中のClientからAPIへアクセスする場合に利用できます。
CloudFrontのネットワークを利用してAPIへアクセスします。
Global Client
↓
CloudFront
↓
API Gateway
Regional
特定のAWS Region内にAPI Endpointを作成します。
独自にCloudFrontを組み合わせたい場合などにも利用できます。
Client
↓
Regional Endpoint
↓
API Gateway
Private
VPC内部からのみ利用するPrivate APIを作成できます。
VPC
↓
VPC Endpoint
↓
Private API Gateway
Lambdaとの統合
API GatewayのBackendとしてLambdaを設定できます。
Client
↓
GET /users/123
↓
API Gateway
↓
Lambda
↓
処理結果
↓
Client
これによってEC2などのWebサーバーを用意しなくても、Serverless APIを構築できます。
Integration Type
REST APIには複数のIntegration Typeがあります。
| Integration | 用途 |
|---|---|
| AWS | AWSサービスとの非Proxy統合 |
| AWS_PROXY | Lambda Proxy Integration |
| HTTP | HTTP Backendとの非Proxy統合 |
| HTTP_PROXY | HTTP BackendとのProxy統合 |
| MOCK | Backendを呼び出さない |
Lambda Proxy Integration
API GatewayとLambdaを連携するときによく使われるのがLambda Proxy Integration(AWS_PROXY) です。
HTTP Requestの情報をLambdaへ渡します。
GET /users/123?detail=true
というRequestなら、
API Gateway
↓
Lambda
Path
Query String
Header
Body
など
の情報をLambda側で利用できます。
Lambda Proxy Integrationと502
特にREST APIのLambda Proxy Integrationでは、LambdaからAPI Gatewayが期待する形式でResponseを返す必要があります。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"message\":\"OK\"}"
}
のような形式です。
Lambdaから不正な形式のResponseを返した場合、
Lambda
↓
不正なResponse形式
↓
API Gateway
↓
502 Bad Gateway
となる場合があります。
Mapping Template
REST APIの非Proxy Integrationでは、RequestやResponseのデータ形式を変換するためにMapping Templateを利用できます。
{
"userId": "user001"
}
というデータが送られてきたとします。
API Gateway側で変換して、
{
"id": "user001"
}
としてBackendへ渡す、といった処理ができます。
Client
↓
Request
↓
API Gateway
↓
Mapping Template
↓
変換
↓
Backend
REST API
→ VTL Mapping Template
HTTP API
→ Parameter Mapping
Stage
API Gatewayでは、APIをStageとしてデプロイできます。
例えば、
dev
test
prod
のように環境を分けられます。
API Gateway
│
├─ dev
├─ test
└─ prod
これによって、同じAPIでも開発環境と本番環境を分離できます。
Stage Variables
Stageごとに異なる値を設定したい場合はStage Variablesを利用できます。
例えば、
dev
→ Lambda DevFunction
prod
→ Lambda ProdFunction
のように環境によってBackendを切り替える構成を作れます。
さらにLambda Aliasと組み合わせることもできます。
例えば、
Stage Variable
alias = dev
として、
${stageVariables.alias}
をLambda Aliasの指定に利用します。
API Gateway
dev Stage
↓
alias = dev
↓
Lambda :dev
prod Stage
↓
alias = prod
↓
Lambda :prod
つまり、
Stage
→ APIの環境
Stage Variables
→ 環境ごとの設定値
Lambda Alias
→ Lambda Versionの切り替え
という関係になります。
Canary Deployment
REST APIのStageでは、Canary Releaseを利用して新しいDeploymentへ一部のTrafficだけを流すことができます。
例えば、
Client
↓
API Gateway
│
├─ 90% → 現在のDeployment
│
└─ 10% → 新しいDeployment
のように、一部のRequestだけを新しい環境へ流して検証できます。
Mock Integration
Backendを呼び出さず、API GatewayだけでResponseを返したい場合はMock Integrationを利用できます。
Client
↓
API Gateway
↓
Mock Integration
↓
Response
つまり、
Lambda
EC2
HTTP Backend
などを呼び出す必要がありません。
API Cache
同じAPIへのRequestが大量に発生する場合、毎回Backendを呼び出すと負荷が増えます。
REST APIではAPI Cacheを利用できます。
Client
↓
API Gateway
↓
Cache
├─ HIT → Response
│
└─ MISS
↓
Lambda
Cacheにデータが存在すればLambdaなどのBackendを呼び出さずにResponseできます。
Backend負荷を減らしたい
+
同じResponseが頻繁に要求される
→ API Cache
という判断ができます。
Usage Plan
APIを利用するClientごとに利用量を管理したい場合、REST APIではUsage Planを利用できます。
例えば、
Free Plan
→ 1日1,000 Request
Premium Plan
→ 1日100,000 Request
のような制御を設定できます。
Throttling
大量のRequestからAPIやBackendを守るために、Throttlingを利用できます。
大量Request
↓
API Gateway
↓
Throttling
↓
Backend
Throttlingには、
API Gateway全体のThrottle
Usage Planなどによる
Client単位のThrottle
など複数のレベルがあります。
Throttling制限を超えた場合、
429 Too Many Requests
が重要なキーワードになります。
API Key
REST APIではAPI Keyを発行して、ClientごとのAPI利用状況を管理できます。
Client
↓
API Key
↓
API Gateway
ただし重要なのは、
API Keyをユーザー認証・認可の仕組みとして考えないことです。
API Keyは主に、
Usage Plan
+
利用量の管理
などに使用します。
API Gatewayの認証・認可
API Gatewayでは複数の認証・認可方式があります。
Cognito
JWT Authorizer
Lambda Authorizer
IAM
Resource Policy
です。
Cognitoによる認証
Cognito User Poolを利用して、APIへアクセスするユーザーを認証できます。
User
↓
Cognito User Pool
↓
Token
↓
API Gateway
↓
Lambda
REST APIではCognito User Pool Authorizerを利用できます。
HTTP APIではJWT Authorizerを利用して、Cognitoなどが発行したJWTを検証できます。
REST API
→ Cognito User Pool Authorizer
HTTP API
→ JWT Authorizer
と整理すると分かりやすいです。
Lambda Authorizer
独自の認証・認可ロジックを実装したい場合はLambda Authorizerを利用できます。
Client
↓
Tokenなど
↓
API Gateway
↓
Lambda Authorizer
↓
認証・認可
↓
Backend
REST APIのLambda Authorizerには主に、
TOKEN
REQUEST
の2種類があります。
TOKEN
Tokenなど1つの認証情報を利用します。
Authorization Header
↓
TOKEN Authorizer
↓
Lambda
REQUEST
複数のRequest情報を認証・認可に利用できます。
Header
Query String
Stage Variable
Context
Lambda Authorizerでは認可結果を一定時間Cacheすることもできます。
認証・認可
↓
結果をCache
↓
Lambda Authorizerの呼び出し削減
IAM認証
AWS IAMを利用してAPIへのアクセスを制御することもできます。
ClientはAWS Signature Version 4(SigV4) でRequestへ署名します。
Client
↓
SigV4署名
↓
API Gateway
↓
IAMで許可?
↓
Backend
Resource Policy
API GatewayにはResource Policyを設定できます。
例えば、
特定IP Addressだけ許可
特定AWS Accountから許可
特定VPC / VPC Endpointから許可
など、APIそのものへのアクセス制御に利用できます。
Client
↓
Resource Policy
↓
API Gateway
CORS
ブラウザから別OriginのAPIへアクセスする場合、CORS(Cross-Origin Resource Sharing) が問題になることがあります。
例えば、
Frontend
https://example.com
↓
API
https://api.example.net
のようにOriginが異なる場合です。
Preflight Request
ブラウザは必要に応じて、本来のRequestを送る前にOPTIONS Requestを送信します。
Browser
↓
OPTIONS
↓
API Gateway
↓
CORS確認
↓
実際のRequest
これをPreflight Requestと呼びます。
CORSでは例えば、
Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Methods
などのResponse Headerが重要になります。
Proxy Integrationでは、必要なCORS HeaderをLambdaのResponseに含める必要があるケースがあります。
AWS WAFとの連携
REST APIではAWS WAFと連携できます。
Client
↓
AWS WAF
↓
API Gateway REST API
↓
Backend
API Gatewayで問題が起きたとき
API Gatewayを利用したServerless APIでは、
Client
↓
API Gateway
↓
Lambda
↓
DynamoDB
と複数のサービスが連携します。
そのため、問題が起きた場所を切り分けることが重要です。
API Gateway
→ API側のRequest / Response
CloudWatch Logs
→ Logs
CloudWatch Metrics
→ 4XX / 5XX / Latencyなど
Lambda
→ Functionの実行状況
X-Ray
→ 分散トレーシング