Amazon API Gateway で API を設計・構築・運用する際のベストプラクティスを、AWS Well-Architected Framework の観点に沿って整理したものです。
目次
- API タイプの選択
- エンドポイントタイプの選択
- セキュリティ
- 信頼性・スロットリング
- パフォーマンス
- 設計・開発
- デプロイ・リリース管理
- 監視・ロギング
- コスト最適化
- 主要なクォータ・制約
- チェックリスト
1. API タイプの選択
API Gateway には 3 種類の API があり、要件に応じて選択します。
| 項目 | REST API | HTTP API | WebSocket API |
|---|---|---|---|
| 用途 | 高機能な API 管理が必要な場合 | シンプル・低コスト・低レイテンシ | 双方向リアルタイム通信 |
| 料金 | 高め | REST API より大幅に安価 | 接続時間 + メッセージ数 |
| API キー / 使用量プラン | ○ | × | × |
| AWS WAF 連携 | ○ | ×(CloudFront 経由で対応) | × |
| リクエスト検証 | ○ | × | ○(ルート単位) |
| キャッシュ | ○ | × | × |
| マッピングテンプレート (VTL) | ○ | ×(パラメータマッピングのみ) | ○ |
| プライベート API | ○ | × | × |
| JWT オーソライザー(ネイティブ) | ×(Cognito / Lambda で対応) | ○ | × |
| レスポンスストリーミング | ○ | × | — |
| エッジ最適化エンドポイント | ○ | × | × |
選択の指針
- まず HTTP API を検討する: Lambda / HTTP バックエンドへのプロキシで、JWT 認証程度で足りるなら HTTP API が最もコスト効率が良い。
- REST API を選ぶべきケース:
- WAF、API キー、使用量プラン、キャッシュ、リクエスト検証が必要
- VPC 内からのみアクセスさせたい(プライベート API)
- AWS サービスへの直接統合で VTL による変換が必要
- 大きなレスポンスや長時間処理をストリーミングで返したい
- WebSocket API: チャット、通知、ダッシュボードのリアルタイム更新など。
2. エンドポイントタイプの選択(REST API)
| タイプ | 特徴 | 推奨ケース |
|---|---|---|
| リージョン | 同一リージョンのクライアント向け。自前の CloudFront を前段に置ける | 多くのケースでの推奨デフォルト |
| エッジ最適化 | AWS 管理の CloudFront を経由 | 地理的に分散したクライアント(ただし CloudFront の設定は制御できない) |
| プライベート | VPC インターフェイスエンドポイント経由でのみアクセス可能 | 社内システム、マイクロサービス間通信 |
推奨: グローバル配信が必要な場合でも、リージョンエンドポイント + 自前の CloudFront の構成にすると、キャッシュポリシー・WAF・カスタムヘッダーなどを細かく制御できる。
その他:
- デュアルスタック(IPv4/IPv6) エンドポイントが全エンドポイントタイプとカスタムドメインで利用可能。IPv6 対応が求められる場合に活用する。
- プライベート API にもカスタムドメイン名を設定できる。
3. セキュリティ
3.1 認証・認可
| 方式 | 適したケース |
|---|---|
| IAM 認証 (SigV4) | AWS 内部サービス間、マシン間通信 |
| Amazon Cognito ユーザープール | エンドユーザー向けアプリ(REST API) |
| JWT オーソライザー | HTTP API で OIDC / OAuth 2.0 プロバイダーと連携 |
| Lambda オーソライザー | 独自トークン、外部 IdP、複雑な認可ロジック |
| リソースポリシー | IP 制限、VPC / VPC エンドポイント制限、アカウント制限 |
| mTLS(相互 TLS) | B2B、IoT など、クライアント証明書による強い認証 |
ベストプラクティス
- すべてのメソッドに認可を設定する。
NONEのまま公開しない(意図的に公開する場合も明示的にドキュメント化)。 - API キーを認証手段として使わない。API キーは使用量プランによる識別・制限用であり、セキュリティ境界ではない。
- Lambda オーソライザーの結果をキャッシュする(TTL の目安 300 秒程度)。キャッシュキー(Identity Source)を適切に設定し、ポリシーのワイルドカード指定に注意する。
- Lambda オーソライザーは最小権限のポリシーを返す。
Resource: "*"を返すとキャッシュ時に他リソースへのアクセスも許可されてしまう。 - Cognito のスコープ(OAuth スコープ) でメソッド単位の認可を行う。
- プライベート API ではリソースポリシーで許可する VPC エンドポイントを明示する。
3.2 通信の保護
- TLS 1.2 以上を強制する。カスタムドメインと REST API エンドポイントでは強化された TLS セキュリティポリシーが選択できるので、より厳格なポリシーを選ぶ。
- デフォルトの
execute-apiエンドポイントを無効化し、カスタムドメイン経由のアクセスのみに限定する(WAF や CloudFront のバイパスを防止)。 - バックエンドへの通信には クライアント証明書(REST API)や VPC リンク を使い、バックエンドを直接インターネットに公開しない。
3.3 AWS WAF
- REST API(または前段の CloudFront)に AWS WAF を適用する。
- AWS マネージドルール(Core Rule Set、Known Bad Inputs、SQLi、IP Reputation など)をベースに導入。
- レートベースルールで IP 単位の過剰リクエストをブロック。
- まず Count モードで誤検知を確認してから Block に切り替える。
3.4 入力検証
- REST API のリクエストバリデーターと JSON Schema モデルで、バックエンドに到達する前に不正リクエストを拒否する(Lambda 実行コストの削減にもなる)。
- 必須のクエリパラメータ・ヘッダーを定義する。
- ペイロードサイズの上限を意識する。
3.5 CORS
Access-Control-Allow-Origin: *を本番で安易に使わない。許可するオリジンを明示する。- プロキシ統合の場合、バックエンド側でも CORS ヘッダーを返す必要がある点に注意。
- エラー時(4XX/5XX)にも CORS ヘッダーが返るよう、ゲートウェイレスポンスを設定する。
3.6 その他
- ゲートウェイレスポンスをカスタマイズし、内部情報(スタックトレース等)を漏らさない。
- API Gateway が CloudWatch Logs に書き込むための IAM ロールは最小権限にする。
- 統合で使う IAM ロール(AWS サービス統合時)も最小権限にする。
- 秘密情報をステージ変数に直接入れない(Secrets Manager / Parameter Store を利用)。
4. 信頼性・スロットリング
4.1 スロットリングの階層
API Gateway のスロットリングは以下の順に適用されます。
- AWS アカウント単位(リージョンごと。デフォルト 10,000 RPS / バースト 5,000)
- ステージ単位 / メソッド単位
- 使用量プラン(クライアント単位)(REST API のみ)
ベストプラクティス
- ステージ / メソッド単位でスロットリングを明示的に設定し、1 つの API がアカウント全体の上限を食い潰さないようにする。
- 外部パートナー向けには 使用量プラン + API キー でクライアントごとのレート・クォータを設定する。
- アカウントレベルの上限が不足しそうな場合は、事前に Service Quotas で引き上げ申請する。
- クライアントは
429 Too Many Requestsに対して エクスポネンシャルバックオフ + ジッターで再試行する。
4.2 タイムアウト
- 統合タイムアウトはデフォルト 29 秒(REST API はリージョン / プライベート API で引き上げ申請可能。HTTP API は最大 30 秒)。
- 長時間処理は 非同期パターン(SQS / Step Functions に投入して 202 を返し、ポーリングや WebSocket で結果通知)に切り替える。
- REST API のレスポンスストリーミングを使うと、統合タイムアウトを最大 15 分まで延ばせ、10 MB を超えるペイロードも返せる。生成 AI の応答や大きなファイル配信に有効。
- バックエンドのタイムアウトは API Gateway のタイムアウトより短く設定し、確実にエラーを返す。
4.3 耐障害性
- マルチリージョン構成: Route 53 のレイテンシー / フェイルオーバールーティング + 各リージョンのカスタムドメインで冗長化。
- バックエンドの保護: API Gateway のスロットリングでバックエンド(特に RDB)の過負荷を防ぐ。Lambda は予約同時実行数と合わせて設計する。
- SQS / EventBridge への直接統合で、Lambda を挟まずにリクエストをバッファリングする(ピーク吸収)。
5. パフォーマンス
- キャッシュ(REST API): 読み取り中心のエンドポイントでステージキャッシュを有効化。TTL・キャッシュキー(パラメータ)を適切に設定し、認可情報を含むキーの扱いに注意する。
- クライアントからのキャッシュ無効化(
Cache-Control: max-age=0)は認可を必須にする。
- クライアントからのキャッシュ無効化(
- CloudFront の活用: 静的に近いレスポンスはエッジでキャッシュ。
- ペイロード圧縮: REST API でコンテンツエンコーディング(
minimumCompressionSize)を有効化し転送量を削減。 - Lambda 統合の最適化: コールドスタート対策(Provisioned Concurrency、SnapStart、軽量ランタイム)、適切なメモリサイズ。
- AWS サービスへの直接統合: DynamoDB、SQS、Step Functions、EventBridge などへは Lambda を挟まず直接統合することで、レイテンシとコストを削減。
- レスポンスストリーミングで Time-to-First-Byte (TTFB) を改善する。
6. 設計・開発
6.1 API 設計
- OpenAPI 定義を正(Single Source of Truth)とする。インポート / エクスポート機能や IaC と組み合わせて管理する。
- リソース指向の URL 設計(名詞の複数形、HTTP メソッドで操作を表現)。
- バージョニング戦略を最初に決める(URL パス
/v1/、カスタムドメインのベースパス、ヘッダーなど)。 - 一貫したエラーレスポンス形式(例: RFC 9457 Problem Details)をゲートウェイレスポンスとバックエンドで統一する。
- 冪等性: POST など副作用のある操作には
Idempotency-Keyヘッダー等で冪等性を担保する。 - ページネーション: 大きなリストを返すエンドポイントにはカーソルベースのページネーションを実装する。
6.2 統合方式
| 統合方式 | 特徴 | 推奨ケース |
|---|---|---|
| Lambda プロキシ統合 | リクエスト全体を Lambda に渡す。最もシンプル | ほとんどの Lambda バックエンド |
| Lambda カスタム統合 | VTL で変換 | 特殊な変換が必要な場合のみ |
| HTTP プロキシ統合 | 既存 HTTP バックエンドへの転送 | 既存システムの API 化 |
| AWS サービス統合 | DynamoDB / SQS などを直接呼び出し | 単純な CRUD、非同期投入 |
| VPC リンク(プライベート統合) | NLB / ALB / Cloud Map 経由で VPC 内へ | ECS / EC2 などのプライベートバックエンド |
- 原則として プロキシ統合 を使い、変換ロジックはバックエンドに寄せる(テスト容易性・可読性のため)。
- VTL を使う場合は複雑化を避け、テストを用意する。
6.3 カスタムドメインとルーティング
- カスタムドメイン名を設定し、クライアントを API ID やステージ名から切り離す。
- REST API では、カスタムドメインのルーティングルールで HTTP ヘッダー値やベースパス(またはその組み合わせ)に基づく動的ルーティングが可能。A/B テスト、セルベースアーキテクチャ、テナント別のバックエンド振り分けなどに活用できる。
- 新規ドメインでは「ルーティングルールのみ」モードが推奨。既存の API マッピングからは「ルーティングルール → API マッピング」モードで段階的に移行する。
- 対象は REST API のみ(HTTP / WebSocket API は対象外)。パブリックとプライベートの混在は不可。
6.4 Infrastructure as Code
- AWS SAM / AWS CDK / CloudFormation / Terraform で API を定義し、手動変更を禁止する。
- コンソールでの手動変更(ドリフト)を検出する仕組みを用意する。
- 環境(dev / stg / prod)は 別アカウントで分離するのが推奨(ステージだけでの分離はクォータやリスクを共有してしまう)。
6.5 AI エージェント連携
- 既存の REST API を AI エージェントから利用させたい場合、API Gateway の MCP プロキシ機能で REST API を MCP 互換エンドポイントとして公開できる(対応リージョンに注意)。
- 外部開発者向けには API Gateway Portals(開発者ポータル機能) で API ドキュメントやキー発行を提供できる。
7. デプロイ・リリース管理
- ステージ(例:
prod)とステージ変数で、バックエンドの Lambda エイリアスやエンドポイントを切り替える。 - カナリアリリース(REST API): ステージのカナリア設定で一部トラフィックを新デプロイに流し、メトリクスを確認してから昇格する。
- Lambda エイリアス + 重み付けルーティング / CodeDeploy と組み合わせて段階的デプロイを行う。
- 自動デプロイ(HTTP API) は開発環境では便利だが、本番では明示的なデプロイを推奨。
- デプロイ前に OpenAPI 定義の Lint(Spectral など)、契約テスト、統合テストを CI で実行する。
- ロールバック手順(以前のデプロイ ID へのステージ切り替え)を確立しておく。
8. 監視・ロギング
8.1 ログ
| ログ種別 | 内容 | 推奨設定 |
|---|---|---|
| アクセスログ | リクエストごとの要約(JSON 形式推奨) | 本番で必ず有効化 |
| 実行ログ | 処理過程の詳細 | 本番は ERROR レベル、調査時のみ INFO |
| データトレース | リクエスト / レスポンス本文 | 本番では無効(機密情報漏洩リスク) |
- アクセスログには最低限以下を含める:
requestId,extendedRequestId,ip,requestTime,httpMethod,resourcePath,status,responseLength,integrationLatency,responseLatency(integration.latency),error.message,authorizer.error,identity.userAgent - アクセスログは Amazon Data Firehose 経由で S3 などへ配信し、長期保管・分析(Athena 等)も可能。
- REST API の実行ログは、より大きなログイベントと配信先の設定(CloudWatch Logs 以外の宛先を含む)に対応している。用途とコストに応じて配信先を選ぶ。
- ログの保持期間を設定する(CloudWatch Logs のデフォルトは無期限でコスト増の原因になる)。
8.2 メトリクスとアラーム
主要な CloudWatch メトリクスにアラームを設定します。
| メトリクス | 見るべき観点 |
|---|---|
5XXError | バックエンド / API Gateway 側の障害 |
4XXError | クライアントエラー、認証失敗、スロットリング(急増に注意) |
Latency / IntegrationLatency | p90 / p99 で監視。差分は API Gateway 自体のオーバーヘッド |
Count | トラフィックの異常(急増・急減) |
CacheHitCount / CacheMissCount | キャッシュ効率 |
- 詳細メトリクス(メソッド単位) は必要な API に限定して有効化(コストがかかるため)。
- CloudWatch 異常検知を活用して静的しきい値の調整負荷を減らす。
8.3 トレーシング
- AWS X-Ray トレーシングを有効化し、API Gateway → Lambda → DynamoDB などのエンドツーエンドのレイテンシを可視化する。
X-Amzn-Trace-Idやリクエスト ID をバックエンドのログにも出力し、相関分析できるようにする。
9. コスト最適化
- 要件が満たせるなら HTTP API を選ぶ(REST API より大幅に安価)。
- キャッシュでバックエンド呼び出しを削減(ただしキャッシュ自体に時間課金がある点に注意)。
- AWS サービス直接統合で不要な Lambda 呼び出しをなくす。
- リクエスト検証で不正リクエストをバックエンド到達前に弾く。
- ログ保持期間の設定、実行ログレベルの適正化、詳細メトリクスの絞り込み。
- データ転送量削減のため レスポンス圧縮 を有効化。
- 大量トラフィックの場合、REST API の段階的料金(リクエスト数に応じた単価低下)も考慮する。
- 未使用のステージ・API・カスタムドメイン・キャッシュクラスターを定期的に棚卸しする。
10. 主要なクォータ・制約
値は変更される可能性があるため、設計時は必ず最新の公式ドキュメント(Service Quotas)を確認すること。
| 項目 | 値(目安) | 備考 |
|---|---|---|
| アカウントあたりのスロットリング | 10,000 RPS / バースト 5,000 | リージョン単位、引き上げ可能 |
| 統合タイムアウト | 50 ms 〜 29 秒(REST)/ 最大 30 秒(HTTP) | REST のリージョン / プライベートは引き上げ申請可。ストリーミング時は最大 15 分 |
| ペイロードサイズ | 10 MB | ストリーミング時は超過可 |
| WebSocket メッセージサイズ | 128 KB(フレーム 32 KB) | |
| WebSocket 接続時間 | 最大 2 時間 | アイドル 10 分で切断 |
| Lambda オーソライザーのキャッシュ TTL | 最大 3,600 秒 |
11. チェックリスト
セキュリティ
- すべてのメソッドに適切な認可(IAM / Cognito / JWT / Lambda オーソライザー)を設定した
- API キーを認証手段として使っていない
- TLS 1.2 以上の(強化された)セキュリティポリシーを適用した
- AWS WAF を適用した(REST API または前段 CloudFront)
- デフォルトの
execute-apiエンドポイントを無効化した(カスタムドメイン使用時) - リクエスト検証(スキーマ)を設定した
- CORS の許可オリジンを限定した
- ゲートウェイレスポンスで内部情報を漏らしていない
- 本番でデータトレースを無効にした
信頼性
- ステージ / メソッド単位のスロットリングを設定した
- 外部クライアント向けに使用量プランを設定した
- 29 秒を超えうる処理は非同期化またはストリーミング化した
- クライアントのリトライ(バックオフ + ジッター)を設計した
- 必要に応じてマルチリージョン構成を検討した
運用
- アクセスログ(JSON)を有効化し、保持期間を設定した
- 5XX / 4XX / レイテンシのアラームを設定した
- X-Ray トレーシングを有効化した
- IaC で管理し、手動変更を禁止した
- カナリアリリースまたは段階的デプロイの仕組みを用意した
- ロールバック手順を確立した
コスト
- API タイプ(HTTP / REST)の選択が要件に対して適切
- 不要な Lambda を挟まず直接統合を検討した
- キャッシュ・圧縮を適切に設定した
- 詳細メトリクス・ログレベルを必要最小限にした