مارک پلاس

تکنولوژی نوین اینترنتی

Versioning در API لاراول

دسته‌بندی‌ها

Versioning در API لاراول
Versioning در API لاراول

الیه! بحث Versioning در API یکی از مفاهیم مهم توی طراحی API حرفه‌ای هست، مخصوصاً وقتی داری یه API عمومی یا بزرگ برای مدت طولانی توسعه می‌دی. چون با گذشت زمان، احتمال اینکه نیاز به تغییر در ساختار یا رفتار API داشته باشی خیلی زیاده — و نمی‌خوای این تغییرات برنامه‌ی کلاینت‌هایی که قبلاً به API وصل شدن رو بشکنه.

در ادامه یه راهنمای کامل از versioning توی API (مخصوصاً در لاراول) برات آوردم:


🔢 Versioning در API — راهنمای جامع برای Laravel


📌 چرا API Versioning مهمه؟

وقتی تغییراتی توی API بدی (مثل تغییر ساختار خروجی، حذف فیلدها، تغییر نام مسیرها)، بهتره نسخه‌ی جدیدی از API ایجاد کنی که با نسخه‌های قبلی تداخلی نداشته باشه.


📁 روش‌های متداول Versioning در API

1. 🛣️ نسخه در مسیر (URL Path)

ساده‌ترین و رایج‌ترین روش:

http
GET /api/v1/users GET /api/v2/users

مزایا:

  • قابل فهم برای همه

  • سازگار با مرورگر

  • لاگ‌گیری و دیباگ راحت‌تر


2. 🧾 نسخه در هدر (Accept Header)

http
GET /api/users Accept: application/vnd.myapp.v1+json

مزایا:

  • URL تمیز می‌مونه

  • مناسب برای APIهای پیشرفته و RESTful

معایب:

  • برای تست در مرورگر یا ابزار ساده سخت‌تره


3. ❓ نسخه به صورت Query String (کمتر استفاده می‌شه)

http
GET /api/users?version=1

کمتر توصیه می‌شه، چون semantically درست نیست و امنیت/قابلیت کش پایین‌تری داره.


🧰 پیاده‌سازی Versioning در Laravel

🎯 روش URL Versioning (مناسب و ساده)

ساخت فایل Route مخصوص نسخه:

bash
routes/api.php routes/api/v1.php routes/api/v2.php

تنظیم در RouteServiceProvider:

php
public function map() { $this->mapApiV1Routes(); $this->mapApiV2Routes(); } protected function mapApiV1Routes() { Route::prefix('api/v1') ->middleware('api') ->namespace($this->namespace . '\Api\V1') ->group(base_path('routes/api/v1.php')); } protected function mapApiV2Routes() { Route::prefix('api/v2') ->middleware('api') ->namespace($this->namespace . '\Api\V2') ->group(base_path('routes/api/v2.php')); }

ساخت کنترلر جداگانه برای هر نسخه:

App\Http\Controllers\Api\V1\UserController App\Http\Controllers\Api\V2\UserController

🧠 توصیه‌های مهم

  • برای هر نسخه، مسیرها و کنترلرهای جداگانه تعریف کن.

  • نسخه‌های قدیمی‌تر رو تا زمانی که کاربران ازشون استفاده می‌کنن پشتیبانی کن.

  • بهتره نسخه‌ها فقط در صورت تغییر breaking تغییر کنن (یعنی تغییراتی که با نسخه قبلی سازگار نیستن).

  • از مستندسازی نسخه‌ها غافل نشو — برای هر نسخه بهتره مستندات جداگانه تهیه کنی.


🔥 ابزارهای مرتبط



 اینجا یه پروژه ساده API با نسخه‌بندی v1 و v2 بر پایه Laravel می‌سازیم، با قابلیت احراز هویت (API Token) و خروجی JSON ساختارمند.


✅ ویژگی‌های پروژه

  • ✅ API نسخه‌بندی شده (/api/v1 و /api/v2)

  • ✅ احراز هویت با Laravel Sanctum

  • ✅ دو کنترلر برای مدیریت کاربران در هر نسخه

  • ✅ خروجی JSON با Resource

  • ✅ Routing مرتب‌شده با namespace


🏗️ قدم اول: ساخت پروژه

bash
laravel new versioned-api cd versioned-api composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate

اضافه کردن middleware به app/Http/Kernel.php:

php
'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ],

📁 ساختار دایرکتوری‌ها

markdown
app/ └── Http/ └── Controllers/ └── Api/ ├── V1/ │ └── UserController.php └── V2/ └── UserController.php routes/ ├── api.php ├── api_v1.php └── api_v2.php

📜 تعریف Route‌ها

در routes/api.php:

php
require __DIR__.'/api_v1.php'; require __DIR__.'/api_v2.php';

در routes/api_v1.php:

php
use Illuminate\Support\Facades\Route; use App\Http\Controllers\Api\V1\UserController; Route::prefix('api/v1')->middleware('auth:sanctum')->group(function () { Route::get('/user', [UserController::class, 'index']); });

در routes/api_v2.php:

php
use Illuminate\Support\Facades\Route; use App\Http\Controllers\Api\V2\UserController; Route::prefix('api/v2')->middleware('auth:sanctum')->group(function () { Route::get('/user', [UserController::class, 'index']); });

🎮 کنترلر نسخه اول - app/Http/Controllers/Api/V1/UserController.php

php
namespace App\Http\Controllers\Api\V1; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\User; class UserController extends Controller { public function index() { return response()->json([ 'version' => 'v1', 'data' => User::select('id', 'name')->get() ]); } }

🚀 کنترلر نسخه دوم - app/Http/Controllers/Api/V2/UserController.php

php
namespace App\Http\Controllers\Api\V2; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\User; class UserController extends Controller { public function index() { return response()->json([ 'version' => 'v2', 'users' => User::all() ]); } }

🔑 ثبت‌نام و دریافت توکن

مسیر ثبت‌نام (در routes/api.php):

php
use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Validation\ValidationException; Route::post('/register', function (Request $request) { $request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users', 'password' => 'required|min:6' ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => bcrypt($request->password), ]); return ['token' => $user->createToken('api-token')->plainTextToken]; });

📬 تست با Postman

  1. POST /api/register → دریافت توکن

  2. در درخواست‌های GET /api/v1/user یا GET /api/v2/user، هدر زیر رو اضافه کن:

css
Authorization: Bearer {token}

محتوای مرتبط

پست‌های مرتبط