API バージョニング戦略:URL、ヘッダー、コンテンツネゴシエーションの最適解

Ashley Innocent

Ashley Innocent

13 3月 2026

API バージョニング戦略:URL、ヘッダー、コンテンツネゴシエーションの最適解

要点

URLバージョニング(/v1/pets)は、ほとんどのチームにとって最も実用的なAPIバージョニング戦略です。視認性が高く、キャッシュ可能で、テストも簡単です。ヘッダーバージョニングとコンテンツネゴシエーションは、より「純粋な」RESTではありますが、複雑さを増します。Modern PetstoreAPIは、セマンティックバージョニングと明確な非推奨ポリシーを持つURLバージョニングを使用しています。

はじめに

あなたのAPIに破壊的変更が必要です。/petsのレスポンス形式を、単なる配列からページネーションメタデータを含むラップされたオブジェクトに変更するからです。既存のクライアントは機能しなくなります。どうしますか?

APIバージョニングが必要です。しかし、どの戦略を選びますか?URLバージョニング(/v1/pets vs /v2/pets)?ヘッダーバージョニング(Accept: application/vnd.petstore.v1+json)?それともコンテンツネゴシエーション?それぞれの方法には熱心な支持者と強い意見があります。

結論から言うと、URLバージョニングがほとんどのチームにとって最適です。実用的で、視認性が高く、すべてのHTTPツールで機能します。ヘッダーバージョニングとコンテンツネゴシエーションは理論的にはよりクリーンですが、ほとんどのチームには不要な複雑さを加えます。

Modern PetstoreAPIは、セマンティックバージョニングと明確な非推奨ポリシーを持つURLバージョニングを使用しています。現在のバージョンはv1で、v2は将来の破壊的変更のために計画されています。

💡
REST APIを構築またはテストしている場合、Apidogは複数のAPIバージョンをテストし、バージョン固有の動作を検証し、後方互換性を確保するのに役立ちます。各バージョンごとに個別の仕様を管理し、すべてのバージョンに対して同時にテストを実行できます。
ボタン

このガイドでは、主要な3つのバージョニング戦略、それぞれのトレードオフ、そしてModern PetstoreAPIを参考にバージョニングを正しく実装する方法を学びます。

APIにバージョニングが必要な理由

APIは進化します。機能を追加し、バグを修正し、設計を改善します。これらの変更が既存のクライアントを破壊することがあります。

破壊的変更

既存のクライアントを破壊する変更点:

1. フィールドの削除:

// v1
{"id": "123", "name": "Fluffy", "age": 3}

// v2 (破壊的変更: ageフィールドが削除された)
{"id": "123", "name": "Fluffy"}

2. フィールドの型の変更:

// v1
{"price": "19.99"}

// v2 (破壊的変更: 文字列から数値へ)
{"price": 19.99}

3. レスポンス構造の変更:

// v1 (単純な配列)
[{"id": "123"}]

// v2 (破壊的変更: ラップされたオブジェクト)
{"data": [{"id": "123"}], "pagination": {...}}

4. URL構造の変更:

// v1
GET /pet/123

// v2 (破壊的変更: 複数形)
GET /pets/123

5. 認証方法の変更:

// v1: クエリパラメータにAPIキー
GET /pets?api_key=xxx

// v2 (破壊的変更: Bearerトークン)
GET /pets
Authorization: Bearer xxx

非破壊的変更

クライアントを破壊しない変更点:

バージョニングの決定

破壊的変更が必要な場合、2つの選択肢があります:

1. すべてのクライアントにアップグレードを強制する - シンプルですが、既存の統合を破壊します

2. 複数のバージョンをサポートする - 手間はかかりますが、後方互換性を維持します

ほとんどの公開APIはオプション2を選択します。バージョニングにより、APIを進化させつつ、クライアントに移行の時間を与えることができます。

URLバージョニング

URLバージョニングは、バージョン番号をURLパスに含めます。

仕組み

GET /v1/pets
GET /v2/pets

バージョンはリソース識別子の一部です。異なるバージョンは異なるリソースです。

利点

1. 視認性が高く、明示的

バージョンはURL内にあります。ログ、ブラウザ履歴、ドキュメントで確認できます。覚えておくべき隠れたヘッダーはありません。

2. テストしやすい

curl https://petstoreapi.com/v1/pets
curl https://petstoreapi.com/v2/pets

シンプルなHTTPリクエストで両方のバージョンをテストできます。

3. すべてのHTTPツールで機能する

ブラウザ、キャッシュ、プロキシ、ロードバランサーは異なるURLとして認識します。各バージョンを独立してルーティング、キャッシュ、ログ記録できます。

4. クライアントにとってシンプル

クライアントはURLを変更するだけです。カスタムヘッダーやコンテンツネゴシエーションロジックは不要です。

5. 廃止しやすい

/v1エンドポイントを削除しても/v2には影響しません。

欠点

1. 「純粋な」RESTではない

RESTの純粋主義者は、/v1/pets/123/v2/pets/123は同じリソースであるため、同じURLを持つべきだと主張します。バージョンはヘッダーまたはコンテンツネゴシエーションで指定すべきだと考えます。

2. URLの汚染

APIには複数のURL空間が存在します:/v1/*/v2/*など。

3. 個々のリソースをバージョニングするのが難しい

1つのエンドポイントだけをバージョニングしたい場合、API全体をバージョニングするか、一貫性を欠くことになります。

実装

URLにメジャーバージョンを含める:

/v1/pets
/v2/pets

マイナーバージョンを含めない:

❌ /v1.2/pets  (細かすぎる)
✅ /v1/pets    (メジャーバージョンのみ)

内部的にセマンティックバージョニングを使用する:

Modern PetstoreAPIは、現在のバージョンとして/v1を持つURLバージョニングを使用しています。

ヘッダーバージョニング

ヘッダーバージョニングは、バージョンをカスタムHTTPヘッダーに含めます。

仕組み

GET /pets
API-Version: 1

GET /pets
API-Version: 2

URLは同じままで、ヘッダーがバージョンを指定します。

利点

1. クリーンなURL

/petsはすべてのバージョンで同じです。/v1/v2のようなプレフィックスはありません。

2. より「RESTful」

リソース識別子(/pets/123)は変更されません。表現がヘッダーに基づいて変更されます。

3. きめ細かいバージョニング

個々のリソースをバージョニングできます:

GET /pets
API-Version: 2

GET /orders
API-Version: 1

欠点

1. 見えない

バージョンはURLにはありません。ヘッダーを確認せずにログやブラウザ履歴で確認することはできません。

2. テストが難しい

curl -H "API-Version: 1" https://petstoreapi.com/pets
curl -H "API-Version: 2" https://petstoreapi.com/pets

ヘッダーを含めるのを忘れてはなりません。

3. キャッシュの複雑さ

キャッシュはAPI-Versionヘッダーを考慮する必要があります。レスポンスにVary: API-Versionが必要です。

4. クライアントの複雑さ

クライアントはカスタムヘッダーロジックを実装する必要があります。すべてのHTTPクライアントがこれを簡単にできるわけではありません。

5. デフォルトバージョンの曖昧さ

クライアントがヘッダーを送信しない場合、どうなりますか?デフォルトを設定する必要がありますが、それは暗黙の動作を生み出します。

実装

カスタムヘッダー:

API-Version: 1

またはAcceptヘッダーを使用:

Accept: application/vnd.petstore.v1+json

Varyヘッダーを含める:

Vary: API-Version

これは、キャッシュ時にヘッダーを考慮するようキャッシュに指示します。

コンテンツネゴシエーション

コンテンツネゴシエーションは、カスタムメディアタイプとともにAcceptヘッダーを使用します。

仕組み

GET /pets
Accept: application/vnd.petstore.v1+json

GET /pets
Accept: application/vnd.petstore.v2+json

バージョンはメディアタイプの一部です。

利点

1. 最も「RESTful」

これはRESTが設計された方法です。同じリソースの異なる表現を扱います。

2. HTTP標準に従う

標準的なHTTPコンテンツネゴシエーションを使用します。

3. 複数のフォーマットをサポート

バージョンとフォーマットを同時に指定できます:

Accept: application/vnd.petstore.v1+json
Accept: application/vnd.petstore.v1+xml

欠点

1. 複雑

クライアントはメディアタイプとコンテンツネゴシエーションを理解する必要があります。

2. テストが難しい

curl -H "Accept: application/vnd.petstore.v1+json" https://petstoreapi.com/pets

3. ツールのサポートが不十分

多くのHTTPクライアントやツールは、カスタムメディアタイプをうまく扱えません。

4. キャッシュの複雑さ

キャッシュはAcceptヘッダーを考慮する必要があります。Vary: Acceptが必要です。

5. ほとんどのAPIには過剰

ほとんどのAPIは、これほどの洗練度を必要としません。

実装

ベンダー固有のメディアタイプ:

Accept: application/vnd.petstore.v1+json

レスポンス:

Content-Type: application/vnd.petstore.v1+json
Vary: Accept

Modern PetstoreAPIがバージョニングを実装する方法

Modern PetstoreAPIは、明確なポリシーを持つURLバージョニングを使用しています。

現在のバージョン: v1

https://petstoreapi.com/v1/pets
https://petstoreapi.com/v1/orders
https://petstoreapi.com/v1/users

すべてのエンドポイントは/v1の下にあります。

バージョンレスポンスヘッダー

すべてのレスポンスにはAPIバージョンが含まれています:

X-API-Version: 1.2.0

これにより、URLにはメジャーバージョンのみが表示されていても、正確なバージョン(メジャー.マイナー.パッチ)がわかります。

非推奨警告

バージョンが非推奨になった場合、レスポンスには以下が含まれます:

Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"

バージョンの発見

ルートエンドポイントは利用可能なバージョンを一覧表示します:

GET https://petstoreapi.com/

{
  "versions": [
    {
      "version": "v1",
      "status": "current",
      "docsUrl": "https://docs.petstoreapi.com/v1"
    }
  ]
}

セマンティックバージョニング

Modern PetstoreAPIは内部的にセマンティックバージョニングに従います:

URLにはメジャーバージョンのみが表示されます。

ApidogでAPIバージョンをテストする

Apidogは複数のAPIバージョンをテストするのに役立ちます。

複数のバージョンをインポートする

各バージョンのOpenAPI仕様をインポートします:

petstore-v1.yaml → 環境: v1
petstore-v2.yaml → 環境: v2

すべてのバージョンに対してテストを実行する

両方のバージョンに対して実行されるテストスイートを作成します:

// v1をテスト
pm.environment.set("baseUrl", "https://petstoreapi.com/v1");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");

// v2をテスト
pm.environment.set("baseUrl", "https://petstoreapi.com/v2");
pm.sendRequest(pm.environment.get("baseUrl") + "/pets");

バージョン固有の動作を検証する

v1とv2が異なる動作をすることを確認します:

// v1は単純な配列を返す
pm.test("v1は配列を返す", function() {
    pm.expect(pm.response.json()).to.be.an('array');
});

// v2はラップされたオブジェクトを返す
pm.test("v2はラップされたオブジェクトを返す", function() {
    pm.expect(pm.response.json()).to.have.property('data');
    pm.expect(pm.response.json()).to.have.property('pagination');
});

非推奨ヘッダーを確認する

非推奨バージョンに適切なヘッダーが含まれていることをテストします:

pm.test("非推奨バージョンにはヘッダーが含まれる", function() {
    pm.response.to.have.header("Deprecation");
    pm.response.to.have.header("Sunset");
});

バージョン非推奨戦略

クライアントを壊すことなく古いバージョンを非推奨にする方法。

1. 早期に非推奨をアナウンスする

クライアントに少なくとも6〜12ヶ月の猶予を与えます:

Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT

2. 移行ガイドを提供する

すべての破壊的変更と移行方法を文書化します:

Link: <https://docs.petstoreapi.com/migration/v1-to-v2>; rel="deprecation"

3. 利用状況を監視する

どのクライアントがまだ非推奨バージョンを使用しているかを追跡します:

X-API-Version: 1.2.0
X-Client-ID: abc123

必要に応じてクライアントに直接連絡します。

4. 段階的なシャットダウン

バージョンをすぐに削除しないでください:

  1. 1~6ヶ月目: 非推奨をアナウンス
  2. 7~9ヶ月目: 非推奨ヘッダーを追加
  3. 10~11ヶ月目: 非推奨バージョンのレート制限を減らす
  4. 12ヶ月目: 非推奨バージョンを削除

5. ドキュメントを保持する

削除後も、古いバージョンのドキュメントを保持してください。クライアントがそれを参照する必要があるかもしれません。

結論

URLバージョニングは、ほとんどのチームにとって最も実用的なAPIバージョニング戦略です。視認性が高く、テストが簡単で、すべてのHTTPツールで機能します。ヘッダーバージョニングとコンテンツネゴシエーションは、より「純粋な」RESTではありますが、複雑さを増します。

Modern PetstoreAPIは、現在のバージョンとして/v1を使用するURLバージョニング、内部的なセマンティックバージョニング、および明確な非推奨ポリシーを使用しています。このアプローチは、実用性と優れたAPI設計のバランスをとっています。

Apidogを使用して、複数のAPIバージョンをテストし、バージョン固有の動作を検証し、バージョン間のスムーズな移行を確実にしてください。

ボタン

よくある質問

URLバージョニングとヘッダーバージョニング、どちらを使うべきですか?

特別な理由がない限り、URLバージョニングを使用してください。よりシンプルで、視認性が高く、テストも簡単です。ヘッダーバージョニングはより「RESTful」ですが、ほとんどのチームには不要な複雑さを加えます。

同時にいくつのバージョンをサポートすべきですか?

最大2つのバージョン(現在と以前)をサポートしてください。それ以上をサポートするとメンテナンスの負担が増大します。クライアントに移行のための6〜12ヶ月の猶予を与え、その後古いバージョンを削除してください。

v0からバージョニングすべきですか、v1からですか?

v1から始めてください。v0は不安定さを意味します。APIがv1にするほど安定していないのであれば、まだ公開リリースしないでください。

すべてのエンドポイントをバージョニングする必要がありますか?

いいえ。破壊的変更を行う場合にのみバージョニングしてください。既存のエンドポイントを変更せずに新しいエンドポイントを追加する場合、新しいバージョンは必要ありません。

URLのマイナーバージョンについてはどうですか?

URLにマイナーバージョンを含めないでください。/v1を使用し、/v1.2は使用しないでください。マイナーバージョンは後方互換性があるので、クライアントはURLを変更する必要がありません。

バージョン固有のバグはどのように処理しますか?

サポートされているすべてのバージョンでバグを修正してください。v1にのみバグが存在する場合、v1で修正してください。バグ修正のためにクライアントにv2へのアップグレードを強制しないでください。

セマンティックバージョニングを使うべきですか?

はい、内部的に使用してください。メジャー.マイナー.パッチバージョンを追跡しますが、URLにはメジャーバージョンのみを公開してください。これにより、非破壊的変更に対する柔軟性が得られます。

1つのエンドポイントだけをバージョニングする必要がある場合はどうすればよいですか?

URLバージョニングの場合、API全体をバージョニングするか、一貫性を欠くことになります。これはトレードオフです。ほとんどのチームは、シンプルさのためにAPI全体をバージョニングすることを受け入れています。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる