naoki.dev

記事検索

タイトル・本文・タグから検索します

ホームに戻る
バックエンド

API Gateway の REST API と HTTP API(v2) を比較する(どちらを選ぶべきか)

目次

AWS で Lambda の前段に API Gateway を置くとき、最初に決めるのが REST API(v1) か HTTP API(v2) かです。名前が紛らわしいですが、両方とも RESTful な HTTP エンドポイントを作る製品で、違いは「機能の多さ」と「料金」です。

先に結論を書くと、こう考えると迷いません。

  • 基本は HTTP API(v2) … 安い・速い・設定が簡潔。Lambda プロキシや JWT 認証だけなら十分
  • REST API(v1) を選ぶのは、以下が必要なとき … APIキー / 使用量プラン(per-client スロットリング) / リクエストバリデーション / WAF / プライベート(VPC)エンドポイント / エッジ最適化 / レスポンスキャッシュ / X-Ray

この記事では、公式のフィーチャーマトリクスと料金表を出典つきで整理し、Terraform の書き味の違いまで見ていきます。

2つの位置づけ

AWS 公式は両者をこう説明しています。

REST APIs support more features than HTTP APIs, while HTTP APIs are designed with minimal features so that they can be offered at a lower price. (REST API は HTTP API より多機能。HTTP API は最小機能に絞ることで低価格を実現している)

つまり REST = 高機能・高価格、HTTP = 最小機能・低価格という素直な棲み分けです。HTTP API は後発で、「Lambda + API Gateway のよくある構成」を安く速く作るために機能を削ぎ落とした製品、と捉えると分かりやすいです。

なお WebSocket API はまた別製品で、この記事の比較対象には含めません。

機能比較(公式マトリクスの要点)

公式の Choose between REST APIs and HTTP APIs から、実務で効く差分だけ抜き出します。

機能 REST API(v1) HTTP API(v2)
エンドポイント: エッジ最適化
エンドポイント: リージョナル
エンドポイント: プライベート(VPC)
AWS WAF
APIキー
per-client レート制限 / 使用量プラン
リクエストバリデーション
リクエストボディ変換(マッピングテンプレート/VTL)
リクエストパラメータ変換
レスポンスキャッシュ
カナリアリリース
X-Ray トレーシング
実行ログ / カスタムゲートウェイレスポンス
自動デプロイ(auto-deploy)
JWT オーソライザー(ネイティブ)
Cognito 認可 ✅(JWT オーソライザー経由)
Lambda オーソライザー
IAM 認可
Lambda / HTTP / AWS サービス統合
プライベート統合(NLB/ALB)
プライベート統合(Cloud Map)
モック統合

ポイントは、「本番運用でよく欲しくなる周辺機能」は REST 側にしかないものが多いこと。特に APIキー・使用量プラン・WAF・リクエストバリデーション・キャッシュ・プライベートエンドポイントあたりは HTTP API では代替を自前で用意する必要があります。

逆に HTTP API 独自の強みは、

  • JWT オーソライザーがネイティブ … Cognito/Auth0 等の OIDC トークンを、Lambda を挟まず検証できる
  • 自動デプロイ … ステージにデプロイを明示的に作らなくても反映される(後述の Terraform が楽になる)
  • Cloud Map プライベート統合 … サービスディスカバリ連携

料金比較

ここが HTTP API を選ぶ最大の理由になりがちです(US East / N.Virginia、API Gateway 料金 より)。

REST API(リージョナル/エッジ最適化):

リクエスト数 単価(100万リクエストあたり)
最初の 3.33 億 $3.50
次の 6.67 億 $2.80
10 億超 $2.38
  • さらにオプションのキャッシュは容量課金(例: 1.6GB で $0.038/時 ≒ $0.912/日)

HTTP API:

リクエスト数 単価(100万リクエストあたり)
最初の 3 億 $1.00
3 億超 $0.90

最初の帯で $3.50 → $1.00、およそ 1/3.5 です。トラフィックが多い API ほど HTTP API のコストメリットが効きます。リクエスト単価が安いだけでなく、HTTP API は低レイテンシに最適化されている点も見逃せません。

料金は変動するので、実際の見積もりは必ず公式の料金ページで最新値を確認してください。

認証・認可の違い

ここは設計判断に直結するので個別に。

  • HTTP API: JWT オーソライザーがネイティブ。Cognito User Pool や外部 OIDC(IdP) の iss / aud を設定するだけで、Lambda を挟まずトークン検証できる。SPA + Cognito のような構成では第一候補
  • REST API: JWT オーソライザーは無い。Cognito と組む場合は「Cognito ユーザープールオーソライザー」を使うか、Lambda オーソライザーで JWT を自前検証する
  • 両者とも Lambda オーソライザー / IAM 認可は使える

「Cognito のトークンをそのまま検証したい」なら HTTP API が圧倒的に楽、というのが実感です。

Terraform の書き味の違い

同じ GET /health を作るだけでも、リソース数がかなり違います。

HTTP API(v2) は簡潔。apigatewayv2_* で数リソース、しかも auto-deploy が使えます。

resource "aws_apigatewayv2_api" "this" {
  name          = "example-http"
  protocol_type = "HTTP"
}
 
resource "aws_apigatewayv2_integration" "lambda" {
  api_id                 = aws_apigatewayv2_api.this.id
  integration_type       = "AWS_PROXY"
  integration_uri        = var.lambda_invoke_arn
  payload_format_version = "2.0"
}
 
resource "aws_apigatewayv2_route" "health" {
  api_id    = aws_apigatewayv2_api.this.id
  route_key = "GET /health"
  target    = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}
 
resource "aws_apigatewayv2_stage" "default" {
  api_id      = aws_apigatewayv2_api.this.id
  name        = "$default"
  auto_deploy = true # ← ルート変更が自動反映される
}

REST API(v1)resource → method → integration → deployment → stage と段が多く、さらに aws_api_gateway_deploymenttriggers を入れないとルート変更が再デプロイされないという定番のハマりどころがあります。

resource "aws_api_gateway_rest_api" "this" {
  name = "example-rest"
  endpoint_configuration { types = ["REGIONAL"] }
}
 
resource "aws_api_gateway_resource" "health" {
  rest_api_id = aws_api_gateway_rest_api.this.id
  parent_id   = aws_api_gateway_rest_api.this.root_resource_id
  path_part   = "health"
}
 
resource "aws_api_gateway_method" "get" {
  rest_api_id   = aws_api_gateway_rest_api.this.id
  resource_id   = aws_api_gateway_resource.health.id
  http_method   = "GET"
  authorization = "NONE"
}
 
resource "aws_api_gateway_integration" "lambda" {
  rest_api_id             = aws_api_gateway_rest_api.this.id
  resource_id             = aws_api_gateway_resource.health.id
  http_method             = aws_api_gateway_method.get.http_method
  type                    = "AWS_PROXY"
  integration_http_method = "POST" # ← Lambda 統合は常に POST
  uri                     = var.lambda_invoke_arn
}
 
resource "aws_api_gateway_deployment" "this" {
  rest_api_id = aws_api_gateway_rest_api.this.id
  # ↓ これが無いとルート変更が再デプロイされない
  triggers = {
    redeploy = sha1(jsonencode([
      aws_api_gateway_resource.health.id,
      aws_api_gateway_method.get.id,
      aws_api_gateway_integration.lambda.id,
    ]))
  }
  lifecycle { create_before_destroy = true }
}
 
resource "aws_api_gateway_stage" "this" {
  rest_api_id   = aws_api_gateway_rest_api.this.id
  deployment_id = aws_api_gateway_deployment.this.id
  stage_name    = "v1"
}

行数・概念数ともに HTTP API のほうが軽く、IaC 保守の観点でも HTTP API が有利です。

ペイロード形式(payload format)にも注意

Lambda プロキシ統合の イベント形式が違います。

  • REST API: いわゆる 1.0 形式(httpMethod / path / multiValueHeaders など)
  • HTTP API: 2.0 がデフォルトrequestContext.http.method / rawPath / cookies など。1.0 も選択可)

{ "statusCode": 200, "body": "..." } を返すレスポンス形式は共通ですが、リクエスト(event)を読むハンドラは形式差の影響を受けるため、REST↔HTTP を後から乗り換えるとハンドラ修正が要ることがあります。ヘルスチェックのように event を読まない関数なら影響なしです。

選び方(フローチャート的に)

  1. APIキー / 使用量プラン / per-client スロットリングが要る? → Yes なら REST
  2. WAF をアタッチしたい? → Yes なら REST(HTTP は非対応)
  3. プライベート(VPC 内)API にしたい? → Yes なら REST
  4. リクエストバリデーション / VTL でのボディ変換 / レスポンスキャッシュが要る? → Yes なら REST
  5. 上のどれも要らないHTTP API(安い・速い・IaC が簡潔)

「まず HTTP API で始めて、上記の機能が必要になったら REST を検討」で多くのケースは回ります。

実プロジェクトでの判断メモ

ちなみに自分のサーバーレステンプレートでは、ヘルスチェックのような単純なエンドポイントでも、あえて REST API(v1) を選ぶ場面がありました。理由は「将来 APIキーや使用量プラン、WAF を足す前提があり、途中で API 種別を乗り換えるコスト(ペイロード形式やオーソライザーの作り直し)を避けたい」というもの。将来必要になる機能から逆算して種別を固定するのは、現実的な判断だと思います。

逆に、要件が固まっていて「JWT 認証 + Lambda だけ、とにかく安く」であれば、迷わず HTTP API です。

まとめ

  • 名前は紛らわしいが、REST = 多機能・高価格 / HTTP = 最小機能・低価格
  • 迷ったら HTTP API(v2)。安い(約 1/3.5)・速い・IaC が簡潔・JWT ネイティブ
  • APIキー / 使用量プラン / WAF / プライベート / バリデーション / キャッシュ / X-Ray が要るなら REST API(v1)
  • 後から乗り換えるとペイロード形式やオーソライザーの作り直しが発生しうるので、将来要件から逆算して選ぶのがおすすめ

参考ソース

関連記事