Versioning API در Laravel — v1، v2 و سازگاری عقبرو
اولین breaking change در API — اپ موبایل قدیمی crash میکند. Versioning از روز اول (حتی اگر فقط v1 دارید) عادت خوبی است. در Laravel سادهترین روش URL prefix است: /api/v1/posts. این مقاله استراتژی و ساختار پوشه را پوشش میدهد.
روشهای رایج versioning
| روش | مثال | نکته |
|---|---|---|
| URL prefix | /api/v1/posts | شفاف، cache-friendly — پیشنهاد ما |
| Header | Accept: application/vnd.app.v1+json | URL تمیز؛ debug سختتر |
| Query | ?version=1 | کمتر حرفهای |
پیادهسازی URL prefix
// routes/api.php
Route::prefix('v1')->group(base_path('routes/api/v1.php'));
Route::prefix('v2')->group(base_path('routes/api/v2.php'));
فایل جدا routes/api/v1.php — تمیزتر از یک فایل غول.
Namespace Controller
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 میتواند Resource متفاوت برگرداند — فیلد جدید بدون شکستن v1.
اشتراک منطق — Service
PostService یکی — فقط transformation و response در v1/v2 فرق کند. معماری لایهای.
Deprecation policy
- اعلام sunset در header:
Deprecation: true - مستندات changelog API
- حداقل ۶–۱۲ ماه overlap v1 و v2
چه زمانی v2 بسازیم؟
حذف فیلد، تغییر type، تغییر semantics endpoint — نه هر feature جدید (اغلب additive در v1 OK است).
تست هر نسخه
it('v1 posts structure', fn () => $this->getJson('/api/v1/posts')->assertJsonStructure(['data' => [['id', 'title']]]));
it('v2 adds reading_time', fn () => $this->getJson('/api/v2/posts')->assertJsonPath('data.0.reading_time', fn ($v) => $v !== null));
جمعبندی
از v1 شروع کنید؛ namespace جدا. ساخت API، خطاها version-aware باشند.