یک REST API در Laravel فقط مجموعه‌ای از routeهای JSON نیست. API قراردادی میان تیم‌ها و نسخه‌های مختلف محصول است. هر ناسازگاری کوچک در نام فیلد، خطا یا pagination به کد شرطی در موبایل و فرانت تبدیل می‌شود. استاندارد خوب یعنی مصرف‌کننده کمتر حدس بزند.

URL را حول منبع طراحی کنید

نام‌های جمع و قابل پیش‌بینی مثل /orders/{order} از endpointهایی با فعل‌های پراکنده خواناترند. عملیات معمول را با HTTP method بیان کنید و action ویژه را فقط وقتی استفاده کنید که واقعاً منبع یا تغییر وضعیت مشخصی دارد؛ مثلاً POST /orders/{order}/cancel.

route model binding راحت است، اما authorization باید جداگانه بررسی شود. پیدا شدن یک مدل به معنی مجازبودن کاربر برای دیدن آن نیست.

ورودی را در مرز سیستم اعتبارسنجی کنید

Form Request هم validation را متمرکز می‌کند و هم controller را خوانا نگه می‌دارد. علاوه بر نوع و طول، قواعد کسب‌وکار و مجوز عملیات را در جای مناسب قرار دهید. پیام خطا باید برای کاربر قابل فهم و برای کلاینت قابل پردازش باشد.

public function rules(): array
{
    return [
        'items' => ['required', 'array', 'min:1'],
        'items.*.product_id' => ['required', 'integer', 'exists:products,id'],
        'items.*.quantity' => ['required', 'integer', 'min:1'],
    ];
}

خروجی را با API Resource کنترل کنید

برگرداندن مستقیم Eloquent model قرارداد API را به ساختار دیتابیس گره می‌زند و ممکن است فیلد حساس یا رابطه ناخواسته را منتشر کند. API Resource نام، نوع و حضور هر فیلد را آشکار می‌کند. رابطه‌ها را با whenLoaded کنترل کنید تا serialization خودش N+1 نسازد.

یک شکل ثابت برای خطا داشته باشید

کلاینت باید بداند خطا همیشه چه فیلدهایی دارد. status code درست، code پایدار برای منطق برنامه، message انسانی، جزئیات فیلد و request ID ترکیب مفیدی است:

{
  "error": {
    "code": "ORDER_NOT_PAYABLE",
    "message": "This order cannot be paid in its current state.",
    "request_id": "01J..."
  }
}

stack trace و پیام خام دیتابیس نباید به production برسند. آن جزئیات در log ساختاریافته و متصل به request ID جای دارند.

Pagination و filter را از ابتدا قابل پیش‌بینی کنید

مجموعه نامحدود دیر یا زود مشکل می‌سازد. limit حداکثر داشته باشید و metadata صفحه یا cursor بعدی را ثابت نگه دارید. برای feedهای بزرگ و داده‌ای که دائم اضافه می‌شود، cursor pagination از offset پایدارتر است.

نام filter و sort را مستند کنید و اجازه ندهید نام ستون دلخواه مستقیم وارد query شود. whitelist هم امنیت را بهتر می‌کند و هم قرارداد API را کنترل‌شده نگه می‌دارد.

احراز هویت، مجوز و rate limit سه موضوع جدا هستند

Sanctum هویت token را مشخص می‌کند؛ Policy می‌گوید این هویت چه کاری مجاز است؛ rate limit هم جلوی مصرف غیرعادی یا اشتباه را می‌گیرد. ترکیب این سه، همراه با لغو token و ثبت رویداد حساس، پایه عملی امنیت API است.

نسخه‌بندی را بر اساس مصرف‌کننده انتخاب کنید

اگر اپ موبایل یا شریک بیرونی دارید که هم‌زمان با backend منتشر نمی‌شود، مسیر /v1 یا قرارداد نسخه‌دار هزینه تغییر شکستن را کم می‌کند. هر تغییر فیلد نیاز به نسخه جدید ندارد؛ افزودن سازگار را از حذف و تغییر معنا جدا کنید و برای نسخه قبلی زمان پایان پشتیبانی بدهید.

مستندات و تست قرارداد

نمونه request، response، خطا و روش auth باید کنار API به‌روز بماند. تست feature برای مسیر موفق، validation، authorization و حالت مهم خطا بیشترین ارزش را دارد. اتصال بیرونی را با fake تست کنید، اما یک تست integration دوره‌ای هم سازگاری واقعی را بسنجد.

برای طراحی یا بازنگری قرارداد یک محصول می‌توانید جزئیات خدمات طراحی API Laravel را ببینید. در API کند نیز مسیر عیب‌یابی Laravel و MySQL معمولاً نقطه شروع خوبی است.

پرسش‌های متداول

برای API لاراول Sanctum بهتر است یا Passport؟

برای SPA، اپ موبایل و tokenهای ساده، Sanctum معمولاً کافی است؛ Passport زمانی مناسب است که OAuth2 کامل لازم دارید.

آیا API از روز اول باید version داشته باشد؟

اگر مصرف‌کننده بیرونی یا چند کلاینت با چرخه انتشار متفاوت دارید، بله. برای API صرفاً داخلی می‌توان نسخه‌بندی را با هزینه کمتر به تعویق انداخت.