第28回: APIバージョニング — 既存クライアントを壊さずに進化させる

章: 第3章: RESTful API設計

APIの仕様を変えたら、古いクライアントが壊れてしまいました

レスポンスのフィールド名を変えたり、必須パラメータを追加したりすると、既存のモバイルアプリやフロントエンドが動作しなくなります。全クライアントが同時にアップデートできるとは限りません。

APIバージョニングを導入することで、旧バージョンを維持しながら新バージョンを開発でき、クライアントが準備できたときに移行できます。

APIバージョニングの実装


<?php
// routes/api.php
Route::prefix('v1')->group(function () {
    Route::apiResource('posts', V1\PostController::class);
});
Route::prefix('v2')->group(function () {
    Route::apiResource('posts', V2\PostController::class);
});
// GET /api/v1/posts -> V1コントローラ
// GET /api/v2/posts -> V2コントローラ

バージョニングなし vs バージョニングあり

観点 バージョニングなし バージョニングあり
仕様変更 全クライアントが即座に影響を受ける バージョン別に対応可能
後方互換性 破壊的変更が難しい 旧バージョンを維持できる
ルート管理 単純 バージョンごとにコントローラを分離
移行計画 難しい バージョンごとに廃止期限を設定

チェックポイント: バージョニングの方法は「URLパス(/v1/)」「クエリパラメータ(?version=1)」「カスタムヘッダ(API-Version: 1)」の3種類があります。URLパスが最も視認性が高くキャッシュしやすいため、一般的に推奨されます。

コントローラの分離方法


<?php
// app/Http/Controllers/Api/V1/PostController.php
namespace App\Http\Controllers\Api\V1;

class PostController extends Controller {
    public function index(): JsonResponse {
        // V1の仕様: 全フィールドを返す
        return response()->json(Post::all());
    }
}

// app/Http/Controllers/Api/V2/PostController.php
namespace App\Http\Controllers\Api\V2;

class PostController extends Controller {
    public function index(): JsonResponse {
        // V2の仕様: ページネーションとフィルタリングに対応
        return response()->json(Post::filter(request()->all())->paginate(20));
    }
}

チェックポイント: 旧バージョンを永続的に維持するのはコスト大です。「V1は〇年〇月まで」のような廃止タイムラインをドキュメントで告知し、クライアントの移行を促しましょう。

まとめ & 次のステップ

  • URLプレフィックス(/api/v1/)でバージョンを分けるのが最もシンプル
  • バージョンごとに名前空間とコントローラを分離して責務を明確にする
  • 旧バージョンの廃止スケジュールをドキュメントで事前告知する

次回は第4章「Laravelフレームワーク」としてLaravelのインストールと構成を学びます。「設定より規約」の考え方でフレームワーク開発を始める方法です。

Related Articles