Версионирование API
Когда API меняется, старые клиенты ломаются. Версионирование позволяет выпускать новые версии, не затрагивая существующих клиентов.
Стратегии
- URL-версия —
/api/v1/posts,/api/v2/posts - Заголовок —
Accept: application/vnd.api.v1+json - Query-параметр —
/api/posts?version=1
URL-версия самая простая и явная. Laravel хорошо поддерживает её через префиксы.
Реализация через префикс
Route::prefix('v1')->group(function () {
Route::apiResource('posts', V1\PostController::class);
});
Route::prefix('v2')->group(function () {
Route::apiResource('posts', V2\PostController::class);
});
URL: /api/v1/posts и /api/v2/posts.
Отдельные контроллеры
app/Http/Controllers/Api/V1/PostController.php
app/Http/Controllers/Api/V2/PostController.php
Разные версии могут возвращать разные поля, использовать разные правила валидации.
Отдельные ресурсы
app/Http/Resources/V1/PostResource.php
app/Http/Resources/V2/PostResource.php
V2 может добавить поля, изменить структуру.
Отдельные роут-файлы
routes/api.php
routes/api_v1.php
routes/api_v2.php
Регистрация в bootstrap/app.php:
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
then: function () {
Route::middleware('api')
->prefix('api/v1')
->group(base_path('routes/api_v1.php'));
Route::middleware('api')
->prefix('api/v2')
->group(base_path('routes/api_v2.php'));
},
)
Депрекация
Когда старая версия больше не нужна:
- Помечаешь её как deprecated в документации
- Возвращаешь заголовок
Deprecation: true - Через несколько релизов удаляешь
return response()->json($data)
->header('Deprecation', 'true')
->header('Sunset', '2027-01-01');
Итоги
- Используй URL-версию для явности
- Отдельные контроллеры и ресурсы на каждую версию
- Не ломай старые версии — выпускай новые
- Предупреждай о депрекации заранее