章: 第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のインストールと構成を学びます。「設定より規約」の考え方でフレームワーク開発を始める方法です。