ساخت REST API در Laravel یکی از مهارتهای مهم برای توسعهدهندگان لاراول است. امروزه بسیاری از وبسایتها و نرمافزارها علاوه بر رابط کاربری، به API نیاز دارند تا بتوانند اطلاعات خود را در اختیار اپلیکیشنهای موبایل، فرانتاندهای مبتنی بر React و Vue، نرمافزارهای دیگر و سرویسهای خارجی قرار دهند.
لاراول ابزارهای مختلفی برای طراحی و پیادهسازی API در اختیار توسعهدهندگان قرار میدهد؛ از تعریف Route و ساخت Controller گرفته تا اعتبارسنجی دادهها، ارتباط با پایگاه داده، تبدیل خروجیها به JSON و مدیریت دسترسی کاربران.
در این مقاله یاد میگیریم چگونه یک REST API برای مدیریت محصولات بسازیم، اطلاعات را از دیتابیس دریافت کنیم، عملیات ایجاد و ویرایش و حذف را انجام دهیم و در نهایت API را با ابزارهایی مانند Postman آزمایش کنیم.
REST API چیست؟
API مخفف Application Programming Interface است و به نرمافزارهای مختلف اجازه میدهد از طریق یک رابط مشخص با یکدیگر ارتباط برقرار کنند.
برای مثال، فرض کنید یک فروشگاه اینترنتی با Laravel ساختهاید. ممکن است بخواهید اطلاعات محصولات آن را در موارد زیر استفاده کنید:
- نمایش محصولات در اپلیکیشن اندروید یا iOS
- نمایش محصولات در یک فرانتاند مبتنی بر React یا Vue
- اتصال فروشگاه به نرمافزار حسابداری
- ارائه اطلاعات محصولات به یک سرویس یا وبسایت دیگر
- ساخت پنل مدیریت جداگانه برای کنترل محصولات
در چنین شرایطی میتوانید بهجای اینکه همه نرمافزارها مستقیماً به دیتابیس متصل شوند، یک API ایجاد کنید. نرمافزارهای دیگر درخواست خود را به API ارسال میکنند و پاسخ را دریافت میکنند.
REST نیز مجموعهای از اصول معماری برای طراحی سرویسهای وب است. در یک REST API معمولاً هر منبع، مانند محصول، کاربر یا سفارش، از طریق یک URL مشخص میشود و عملیات موردنظر با متد HTTP تعیین میشود.
برای مثال:
| متد HTTP | مسیر نمونه | کاربرد |
|---|---|---|
| GET | /api/products | دریافت فهرست محصولات |
| GET | /api/products/10 | دریافت محصول شماره ۱۰ |
| POST | /api/products | ایجاد محصول جدید |
| PUT | /api/products/10 | جایگزینی کامل اطلاعات قابلویرایش محصول |
| PATCH | /api/products/10 | ویرایش بخشی از اطلاعات محصول |
| DELETE | /api/products/10 | حذف محصول |
نکته مهم این است که REST API الزاماً به معنای استفاده از Laravel نیست؛ بلکه لاراول ابزارهایی را فراهم میکند تا بتوانیم چنین سرویسی را با سرعت و ساختار مناسب پیادهسازی کنیم.
چرا برای ساخت API از Laravel استفاده کنیم؟
لاراول امکانات زیادی دارد که پیادهسازی API را سادهتر میکنند.
۱. تعریف ساده مسیرها: میتوانید مسیرهای دریافت، ایجاد، ویرایش و حذف اطلاعات را بهسادگی تعریف کنید.
۲. ارتباط با دیتابیس: با استفاده از Eloquent ORM و Query Builder میتوانید اطلاعات را دریافت یا تغییر دهید.
۳. اعتبارسنجی دادهها: سیستم Validation کمک میکند اطلاعات نامعتبر پیش از ذخیرهسازی بررسی شوند.
۴. خروجی JSON: لاراول میتواند دادهها را در قالب JSON به کلاینت ارسال کند.
۵. احراز هویت: ابزارهایی مانند Laravel Sanctum امکان محافظت از API و شناسایی کاربران را فراهم میکنند.
۶. مدیریت خطا: میتوانید خطاهای اعتبارسنجی، دسترسی و پیدا نشدن منابع را به شکل استاندارد به کلاینت برگردانید.
اگر هنوز با مفاهیم پایه آشنا نیستید، پیشنهاد میکنیم ابتدا مقالههای آموزش Route در Laravel، آموزش Controller در Laravel و آموزش Validation در Laravel را مطالعه کنید.
پیشنیازهای ساخت REST API در Laravel
برای پیادهسازی مثال این مقاله، بهتر است با موارد زیر آشنا باشید:
- ساخت پروژه Laravel
- کار با Route و Controller
- مفاهیم مدل و Migration
- کار با Eloquent ORM
- اعتبارسنجی اطلاعات ورودی
- آشنایی مقدماتی با درخواستهای HTTP و ساختار JSON
در مثالهای این مقاله از مدل Product برای مدیریت محصولات استفاده میکنیم. فرض میکنیم پروژه لاراول از قبل ساخته شده و پایگاه داده آن نیز پیکربندی شده است.
دستور زیر را اجرا کنید تا نسخه لاراول نصبشده را مشاهده کنید:
php artisan --version
دستورات مربوط به نصب API در نسخههای جدید لاراول با نسخههای قدیمی تفاوت دارند. در این آموزش، مسیرهای API در نسخههای جدیدی که از دستور install:api پشتیبانی میکنند توضیح داده میشوند؛ در نسخههای قدیمیتر ممکن است لازم باشد routes/api.php را به روش دیگری ایجاد یا فعال کنید.
مرحله اول: فعال کردن مسیرهای API در Laravel
در نسخههای جدید لاراول، برای نصب زیرساخت اولیه API میتوانید از دستور زیر استفاده کنید:
php artisan install:api
این دستور در نسخههای پشتیبانیشده، زیرساخت موردنیاز API را نصب یا پیکربندی میکند و فایل مسیرهای API را در اختیار پروژه قرار میدهد. جزئیات دقیق آن ممکن است براساس نسخه لاراول و وضعیت فعلی پروژه متفاوت باشد.
پس از اجرا، فایل زیر را بررسی کنید:
routes/api.php
مسیرهایی که در این فایل تعریف میشوند، بهطور پیشفرض با پیشوند /api در دسترس هستند.
برای مثال، اگر این مسیر را تعریف کنید:
Route::get('/products', function () {
return response()->json([
'message' => 'Products API is working',
]);
});
آدرس درخواست به شکل زیر خواهد بود:
GET /api/products
برای مشاهده مسیرهای ثبتشده نیز میتوانید دستور زیر را اجرا کنید:
php artisan route:list --path=api
اگر دستور install:api در نسخه شما وجود ندارد، نسخه لاراول را بررسی کنید و مطابق ساختار همان نسخه، مسیرهای API را در bootstrap/app.php یا ساختار مربوط به نسخه قدیمیتر فعال کنید.
مرحله دوم: ساخت مدل و Migration برای محصولات
برای اینکه API بتواند اطلاعات واقعی محصولات را ذخیره و دریافت کند، ابتدا باید ساختار جدول محصولات را بسازیم.
دستور زیر را اجرا کنید:
php artisan make:model Product -m
این دستور مدل Product و فایل Migration مربوط به آن را ایجاد میکند.
فایل Migration جدید را در مسیر database/migrations باز کنید و متد up را به شکل زیر تنظیم کنید:
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description')->nullable();
$table->decimal('price', 12, 2);
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
در این ساختار، هر محصول دارای نام، توضیحات اختیاری، قیمت و وضعیت فعال یا غیرفعال است.
حالا Migration را اجرا کنید:
php artisan migrate
توجه: دستور بالا ساختار جدول را در دیتابیس ایجاد میکند. قبل از اجرای Migration روی سرور اصلی، از دیتابیس نسخه پشتیبان تهیه کنید و مطمئن شوید تغییرات با ساختار فعلی پروژه تداخل ندارند.
مرحله سوم: تنظیم مدل Product
فایل زیر را باز کنید:
app/Models/Product.php
سپس مدل را به شکل زیر تنظیم کنید:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'description',
'price',
'is_active',
];
protected function casts(): array
{
return [
'price' => 'decimal:2',
'is_active' => 'boolean',
];
}
}
خاصیت fillable مشخص میکند کدام فیلدها از طریق عملیات انتساب گروهی قابل مقداردهی باشند. این کار به جلوگیری از تغییر ناخواسته فیلدهای حساس کمک میکند.
در این مثال، فیلدهایی مانند id و زمانهای ایجاد و ویرایش را از ورودی کاربر نمیپذیریم.
متد casts نیز باعث میشود مقدار is_active بهصورت بولی در مدل در دسترس باشد.
در برخی نسخههای قدیمیتر لاراول ممکن است ترجیح دهید از خاصیت $casts استفاده کنید. اگر نسخه پروژه شما از ساختار متفاوتی پشتیبانی میکند، از مستندات همان نسخه کمک بگیرید.
مرحله چهارم: ساخت Controller برای API
حالا باید کنترلری ایجاد کنیم که مسئول اجرای عملیات مربوط به محصولات باشد.
دستور زیر را اجرا کنید:
php artisan make:controller Api/ProductController
فایل کنترلر در مسیر زیر ایجاد میشود:
app/Http/Controllers/Api/ProductController.php
کنترلر واسطهای بین درخواست کاربر و منطق برنامه است. در این مثال، عملیات دریافت فهرست محصولات، نمایش یک محصول، ایجاد، ویرایش و حذف را در همین کنترلر پیادهسازی میکنیم.
مرحله پنجم: دریافت فهرست محصولات
ابتدا متد دریافت محصولات را به کنترلر اضافه میکنیم.
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index(): JsonResponse
{
$products = Product::query()
->where('is_active', true)
->latest()
->paginate(15);
return response()->json($products);
}
}
در این کد، فقط محصولات فعال دریافت میشوند. سپس نتایج براساس زمان ایجاد مرتب شده و با صفحهبندی ۱۵ محصول در هر صفحه برگردانده میشوند.
نمونه درخواست:
GET /api/products
Accept: application/json
پاسخ شامل اطلاعات محصولات و اطلاعات صفحهبندی خواهد بود؛ برای مثال، تعداد کل نتایج و آدرس صفحههای بعدی.
استفاده از صفحهبندی در APIهایی که ممکن است هزاران رکورد داشته باشند اهمیت زیادی دارد، زیرا دریافت تمام اطلاعات در یک درخواست میتواند باعث مصرف زیاد حافظه و افزایش زمان پاسخ شود.
مرحله ششم: نمایش یک محصول مشخص
برای دریافت جزئیات یک محصول، متد show را اضافه کنید:
public function show(Product $product): JsonResponse
{
return response()->json($product);
}
این متد از Route Model Binding استفاده میکند. یعنی اگر شناسه محصول در مسیر قرار بگیرد، لاراول تلاش میکند رکورد متناظر را از دیتابیس پیدا کند و به متد کنترلر تحویل دهد.
برای مثال:
GET /api/products/10
Accept: application/json
اگر محصول شماره ۱۰ وجود داشته باشد، اطلاعات آن برگردانده میشود. در صورت پیدا نشدن رکورد، لاراول بهصورت پیشفرض پاسخ 404 ارسال میکند.
در پروژههای واقعی ممکن است بخواهید نمایش محصول غیرفعال، محصول متعلق به کاربر دیگر یا محصول خصوصی را محدود کنید. این محدودیتها باید متناسب با قوانین کسبوکار و سطح دسترسی کاربران پیادهسازی شوند.
مرحله هفتم: اعتبارسنجی و ایجاد محصول جدید
برای ایجاد محصول، باید اطلاعات ارسالشده از طرف کلاینت را اعتبارسنجی کنیم.
متد زیر را به ProductController اضافه کنید:
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'description' => ['nullable', 'string'],
'price' => ['required', 'numeric', 'min:0'],
'is_active' => ['sometimes', 'boolean'],
]);
$product = Product::create($validated);
return response()->json([
'message' => 'محصول با موفقیت ایجاد شد.',
'data' => $product,
], 201);
}
در این متد، نام و قیمت محصول اجباری هستند. توضیحات اختیاری است و وضعیت فعال بودن نیز در صورت ارسال، باید مقدار بولی معتبر داشته باشد.
اگر دادهها معتبر باشند، محصول در دیتابیس ذخیره شده و پاسخ HTTP با کد 201 Created برگردانده میشود.
اگر دادهها معتبر نباشند، لاراول پاسخ خطای اعتبارسنجی را ارسال میکند. برای درخواستهای API که انتظار JSON دارند، معمولاً پاسخ شامل کد HTTP 422 Unprocessable Content و جزئیات خطاها خواهد بود.
نمونه درخواست ایجاد محصول:
POST /api/products
Content-Type: application/json
Accept: application/json
بدنه JSON:
{
"name": "کیبورد مکانیکی",
"description": "کیبورد مناسب برنامهنویسی",
"price": 2500000,
"is_active": true
}
نکته امنیتی: در این مثال فرض شده است ایجاد محصول مجاز است. در یک فروشگاه واقعی، معمولاً فقط مدیر یا فروشنده مجاز باید بتواند محصول ایجاد کند. اعتبارسنجی دادهها بهتنهایی جایگزین احراز هویت و بررسی مجوز نیست.
مرحله هشتم: ویرایش اطلاعات محصول
برای ویرایش محصول، متد update را اضافه کنید:
public function update(
Request $request,
Product $product
): JsonResponse {
$validated = $request->validate([
'name' => ['sometimes', 'required', 'string', 'max:255'],
'description' => ['sometimes', 'nullable', 'string'],
'price' => ['sometimes', 'required', 'numeric', 'min:0'],
'is_active' => ['sometimes', 'boolean'],
]);
$product->update($validated);
return response()->json([
'message' => 'محصول با موفقیت ویرایش شد.',
'data' => $product->refresh(),
]);
}
در این مثال، استفاده از sometimes به این معناست که هر فیلد فقط در صورت ارسال شدن اعتبارسنجی میشود. در نتیجه کلاینت میتواند تنها فیلدهایی را که نیاز به تغییر دارند ارسال کند.
نمونه درخواست:
PATCH /api/products/10
Content-Type: application/json
Accept: application/json
بدنه:
{
"price": 2750000
}
در این درخواست فقط قیمت محصول تغییر میکند.
تفاوت مهم PUT و PATCH در طراحی API این است که PUT معمولاً برای جایگزینی کامل نمایش قابلویرایش یک منبع و PATCH برای تغییر بخشی از آن استفاده میشود. در عمل، نحوه دقیق اعتبارسنجی و بهروزرسانی باید با قرارداد API شما سازگار باشد.
مرحله نهم: حذف محصول
برای حذف محصول، متد زیر را اضافه کنید:
public function destroy(Product $product): JsonResponse
{
$product->delete();
return response()->json([
'message' => 'محصول با موفقیت حذف شد.',
]);
}
در صورت موفقیت، پاسخ با کد پیشفرض 200 OK و یک پیام JSON برگردانده میشود.
نمونه درخواست:
DELETE /api/products/10
Accept: application/json
میتوان بهجای آن از پاسخ 204 No Content نیز استفاده کرد؛ در این حالت، پاسخ نباید بدنه داشته باشد.
در پروژههای فروشگاهی واقعی، حذف دائمی همیشه انتخاب مناسبی نیست. اگر محصول به سفارشها یا سوابق مالی متصل باشد، ممکن است استفاده از Soft Delete یا غیرفعال کردن محصول انتخاب امنتری باشد.
مرحله دهم: تعریف Routeهای REST API
حالا که متدهای کنترلر را ساختهایم، باید مسیرهای مربوط به آنها را تعریف کنیم.
فایل زیر را باز کنید:
routes/api.php
کد زیر را در آن قرار دهید:
<?php
use App\Http\Controllers\Api\ProductController;
use Illuminate\Support\Facades\Route;
Route::apiResource('products', ProductController::class);
با این دستور، لاراول مسیرهای استاندارد مربوط به عملیات اصلی منبع محصولات را ثبت میکند.
بهصورت پیشفرض، apiResource مسیرهای مربوط به دریافت فهرست، ایجاد، نمایش، ویرایش و حذف را میسازد؛ برخلاف resource معمولی، مسیرهای مربوط به فرمهای HTML مانند create و edit را ایجاد نمیکند.
خلاصه مسیرها:
| متد | مسیر | متد کنترلر |
|---|---|---|
| GET | /api/products | index |
| POST | /api/products | store |
| GET | /api/products/{product} | show |
| PUT | /api/products/{product} | update |
| PATCH | /api/products/{product} | update |
| DELETE | /api/products/{product} | destroy |
برای بررسی دقیق مسیرهای ثبتشده، دستور زیر را اجرا کنید:
php artisan route:list --path=api
اگر مسیرهای جدید نمایش داده نمیشوند، مطمئن شوید فایل routes/api.php بهدرستی فعال شده و کد Routeها در همان فایل قرار گرفته است. در صورت استفاده از Route Cache نیز میتوانید پس از بررسی شرایط پروژه، کش مسیرها را پاک کنید:
php artisan route:clear
مرحله یازدهم: استفاده از API Resource برای استانداردسازی خروجی
تا اینجا اطلاعات مدل را مستقیماً به JSON تبدیل کردیم. این روش برای مثالهای ساده مناسب است، اما در پروژههای بزرگ بهتر است ساختار پاسخ API را از ساختار داخلی مدل جدا کنیم.
برای این کار از API Resource استفاده میکنیم.
ابتدا دستور زیر را اجرا کنید:
php artisan make:resource ProductResource
سپس فایل زیر را باز کنید:
app/Http/Resources/ProductResource.php
محتوای متد toArray را به شکل زیر تنظیم کنید:
public function toArray(
\Illuminate\Http\Request $request
): array {
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'price' => $this->price,
'is_active' => $this->is_active,
'created_at' => $this->created_at,
];
}
اکنون میتوانیم بهجای برگرداندن مستقیم مدل، از Resource استفاده کنیم.
برای فهرست محصولات:
use App\Http\Resources\ProductResource;
public function index()
{
$products = Product::query()
->where('is_active', true)
->latest()
->paginate(15);
return ProductResource::collection($products);
}
برای نمایش یک محصول:
public function show(Product $product)
{
return new ProductResource($product);
}
همین الگو را میتوان در متدهای ایجاد و ویرایش نیز استفاده کرد تا تمام پاسخها ساختار مشخصی داشته باشند.
مزیت API Resource این است که کنترل میکنید کدام فیلدها در پاسخ ظاهر شوند. بنابراین لازم نیست تمام فیلدهای داخلی مدل را به کلاینت نمایش دهید.
اگر بعداً ساختار دیتابیس تغییر کند، میتوانید تا حد زیادی قرارداد خروجی API را مستقل از مدل نگه دارید.
برای اطلاعات بیشتر میتوانید مقاله آموزش API Resource در Laravel را مطالعه کنید، در صورتی که این مقاله در سایت منتشر شده باشد.
مرحله دوازدهم: مدیریت خطاها و کدهای وضعیت HTTP
یک API مناسب فقط دادههای موفق را برنمیگرداند؛ بلکه باید خطاها را نیز به شکل قابلفهم و قابلپیشبینی مدیریت کند.
کدهای وضعیت متداول عبارتاند از:
| کد HTTP | مفهوم | نمونه کاربرد |
|---|---|---|
200 OK | درخواست موفق | دریافت یا ویرایش اطلاعات |
201 Created | منبع جدید ایجاد شده است | ایجاد محصول |
204 No Content | درخواست موفق بدون بدنه پاسخ | حذف محصول |
400 Bad Request | درخواست نامعتبر | ساختار نادرست درخواست |
401 Unauthorized | احراز هویت انجام نشده است | ارسال نشدن توکن معتبر |
403 Forbidden | دسترسی مجاز نیست | کاربر اجازه حذف محصول را ندارد |
404 Not Found | منبع پیدا نشد | محصول ناموجود |
422 Unprocessable Content | اعتبارسنجی شکست خورده است | قیمت نامعتبر |
429 Too Many Requests | تعداد درخواستها بیش از حد مجاز است | عبور از محدودیت نرخ درخواست |
500 Internal Server Error | خطای داخلی سرور | خطای پیشبینینشده برنامه |
برای مثال، اگر ورودی نامعتبر باشد، بهتر است بهجای بازگرداندن پیام کلی «خطا رخ داد»، خطای اعتبارسنجی مشخص و کد وضعیت مناسب ارسال شود.
در محیط توسعه، بررسی لاگها برای پیدا کردن علت خطا مفید است. در محیط عملیاتی، نباید جزئیات داخلی سرور، اطلاعات اتصال دیتابیس، Stack Trace یا اطلاعات محرمانه را به کاربر نمایش دهید.
مرحله سیزدهم: محافظت از API با Laravel Sanctum
بسیاری از APIها فقط برای کاربران واردشده یا کاربران دارای مجوز مشخص قابل استفاده هستند. برای مثال، در یک فروشگاه اینترنتی ممکن است همه کاربران بتوانند محصولات فعال را ببینند، اما فقط مدیران بتوانند محصول ایجاد یا حذف کنند.
Laravel Sanctum یکی از ابزارهای رایج لاراول برای احراز هویت API و SPA است.
اگر Sanctum در پروژه نصب و پیکربندی شده باشد، میتوانید مسیرهای محافظتشده را با Middleware زیر مشخص کنید:
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('products', ProductController::class)
->except(['index', 'show']);
});
با این ساختار، مسیرهای ایجاد، ویرایش و حذف محصول به احراز هویت نیاز خواهند داشت؛ اما مسیرهای فهرست و نمایش محصول خارج از این گروه قرار میگیرند.
این کد بهتنهایی دسترسی مدیر را تضمین نمیکند. هر کاربری که احراز هویت شده باشد، ممکن است بتواند به مسیرهای گروه دسترسی پیدا کند، مگر اینکه مجوزهای مناسب نیز تعریف شده باشند.
برای مثال، میتوانید از Policy یا Gate برای بررسی مجوز ایجاد و ویرایش محصول استفاده کنید. همچنین اگر هر کاربر فقط باید به محصولات خودش دسترسی داشته باشد، باید مالکیت منبع را نیز بررسی کنید.
اگر میخواهید احراز هویت توکنی، ساخت توکن، لغو توکن و محافظت از API را بهصورت کامل یاد بگیرید، مقاله آموزش Laravel Sanctum را مطالعه کنید.
مرحله چهاردهم: آزمایش REST API با Postman
پس از پیادهسازی API، باید مطمئن شویم مسیرها و پاسخها بهدرستی کار میکنند.
Postman ابزاری برای ارسال درخواستهای HTTP و مشاهده پاسخ سرور است. میتوانید آن را برای آزمایش عملیات مختلف API استفاده کنید.
برای دریافت فهرست محصولات:
- متد درخواست را روی
GETقرار دهید. - آدرس
/api/productsرا وارد کنید. - درخواست را ارسال کنید.
- کد وضعیت و بدنه JSON پاسخ را بررسی کنید.
برای ایجاد محصول:
- متد درخواست را روی
POSTقرار دهید. - آدرس
/api/productsرا وارد کنید. - در بخش Body، گزینه
rawو قالبJSONرا انتخاب کنید. - اطلاعات محصول را وارد کنید.
- درخواست را ارسال کنید.
برای مثال:
{
"name": "مانیتور ۲۷ اینچ",
"description": "مانیتور مناسب کارهای روزمره",
"price": 8500000,
"is_active": true
}
برای ویرایش و حذف نیز از متدهای PATCH و DELETE استفاده کنید.
اگر مسیر محافظتشدهای با Sanctum آزمایش میکنید، باید روش احراز هویت مناسب پروژه را نیز تنظیم کنید. در احراز هویت توکنی، معمولاً از سربرگ Authorization با مقدار Bearer YOUR_TOKEN استفاده میشود.
همچنین بهتر است برای درخواستهای دارای JSON، سربرگ Accept: application/json را تنظیم کنید تا پاسخ خطاهای اعتبارسنجی به شکل مناسب API ارائه شود.
مرحله پانزدهم: آزمایش API با cURL
اگر نمیخواهید از Postman استفاده کنید، ابزار خط فرمان cURL نیز برای آزمایش درخواستها مناسب است.
برای دریافت فهرست محصولات:
curl -H "Accept: application/json" \
http://127.0.0.1:8000/api/products
برای ایجاد محصول:
curl -X POST http://127.0.0.1:8000/api/products \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"Mouse","price":500000,"is_active":true}'
این درخواست زمانی موفق خواهد بود که مسیر ایجاد محصول بدون Middleware احراز هویت محافظت شده باشد یا احراز هویت موردنیاز نیز در درخواست ارسال شود.
برای آزمایش API در محیط محلی، میتوانید سرور توسعه لاراول را با دستور زیر اجرا کنید:
php artisan serve
سپس درخواستها را به آدرس http://127.0.0.1:8000 ارسال کنید.
مرحله شانزدهم: نکات امنیتی مهم در طراحی REST API
ساخت API تنها به تعریف Route و برگرداندن JSON محدود نمیشود. برای استفاده در پروژه واقعی باید امنیت و کنترل دسترسی را از ابتدا در نظر بگیرید.
۱. اعتبارسنجی تمام ورودیها
به دادههای دریافتی از کلاینت اعتماد نکنید. اطلاعاتی مانند قیمت، شناسه کاربر، وضعیت سفارش و سطح دسترسی باید در سمت سرور بررسی شوند.
برای مثال، اگر قیمت محصول از دیتابیس مشخص میشود، نباید هنگام ثبت سفارش قیمت ارسالی کاربر را بدون بررسی مبنای محاسبه قرار دهید.
۲. احراز هویت و مجوز دسترسی
احراز هویت مشخص میکند کاربر چه کسی است؛ مجوز دسترسی مشخص میکند آن کاربر اجازه انجام چه عملی را دارد.
این دو مفهوم با یکدیگر متفاوتاند. حتی یک کاربر واردشده نیز نباید بتواند اطلاعات یا منابعی را که اجازه دسترسی به آنها را ندارد مشاهده یا تغییر دهد.
۳. جلوگیری از Mass Assignment
از تعریف درست $fillable یا $guarded اطمینان حاصل کنید. همچنین فقط دادههایی را که اعتبارسنجی شدهاند به مدل منتقل کنید.
۴. محدود کردن تعداد درخواستها
برای جلوگیری از ارسال بیش از حد درخواستها، از Rate Limiting استفاده کنید. محدودیتها را براساس نوع API، سطح دسترسی و نیازهای سرویس تنظیم کنید.
۵. مدیریت امن توکنها
توکنهای API را در لاگها یا پیامهای خطا ثبت نکنید. توکنهایی را که دیگر لازم نیستند لغو کنید و مجوزهای آنها را متناسب با نیاز محدود نگه دارید.
۶. استفاده از HTTPS
در محیط عملیاتی، ارتباطات API باید از HTTPS استفاده کنند تا اطلاعات در مسیر انتقال محافظت شوند.
۷. جلوگیری از افشای اطلاعات داخلی
در پاسخهای API فقط اطلاعات لازم را برگردانید. فیلدهایی مانند رمز عبور، توکنهای خصوصی و اطلاعات محرمانه نباید در خروجی عمومی قرار بگیرند.
۸. کنترل CORS
اگر API از یک دامنه دیگر توسط مرورگر فراخوانی میشود، تنظیمات CORS باید متناسب با دامنهها و روشهای موردنیاز باشد. CORS جایگزین احراز هویت یا مجوز دسترسی نیست.
مرحله هفدهم: بهترین روشها برای طراحی API در Laravel
برای اینکه API در آینده قابل توسعه و نگهداری باشد، بهتر است از ابتدا چند اصل را رعایت کنید.
از نامگذاری منبعمحور استفاده کنید. برای مثال، /api/products معمولاً از مسیری مانند /api/getAllProducts مناسبتر است؛ زیرا نوع عملیات را متد HTTP مشخص میکند.
از API Resource استفاده کنید. این ابزار ساختار پاسخ را از مدل جدا میکند و کنترل بیشتری روی دادههای خروجی میدهد.
برای دادههای زیاد صفحهبندی داشته باشید. ارسال هزاران رکورد در یک پاسخ میتواند مصرف منابع را افزایش دهد.
کدهای وضعیت مناسب برگردانید. کلاینت باید بتواند موفقیت یا شکست درخواست را براساس وضعیت HTTP تشخیص دهد.
اعتبارسنجی را از منطق اصلی جدا کنید. در فرمهای پیچیده میتوانید از Form Request استفاده کنید تا قوانین اعتبارسنجی و مجوزهای مربوط به درخواست ساختار مشخصی داشته باشند.
نسخهبندی را برای APIهای عمومی در نظر بگیرید. برای مثال، مسیر /api/v1/products میتواند به حفظ سازگاری کلاینتها هنگام تغییرات بزرگ کمک کند. نسخهبندی برای تمام پروژهها ضروری نیست، اما برای APIهای عمومی و در حال توسعه مفید است.
منطق پیچیده کسبوکار را در Controller انباشته نکنید. با بزرگتر شدن پروژه، میتوانید منطق را به کلاسهای سرویس، اکشنها یا بخشهای مناسب معماری برنامه منتقل کنید.
قرارداد API را مستند کنید. مشخص کنید هر مسیر چه ورودیهایی میپذیرد، چه پاسخهایی دارد و در چه شرایطی خطا برمیگرداند. این کار برای همکاری با توسعهدهندگان فرانتاند و موبایل بسیار مهم است.
تفاوت REST API با API معمولی چیست؟
اصطلاح API مفهوم گستردهای دارد و REST API یکی از روشهای طراحی آن است.
هر API الزاماً RESTful نیست. برای مثال، GraphQL و RPC نیز الگوهای دیگری برای ارتباط میان نرمافزارها هستند.
REST API معمولاً از منابع مشخص، متدهای HTTP و قراردادهای روشن برای درخواست و پاسخ استفاده میکند. این ساختار باعث میشود طراحی، آزمایش و نگهداری سرویس در بسیاری از پروژهها سادهتر شود.
سوالات متداول درباره ساخت REST API در Laravel
آیا برای ساخت API در Laravel باید فرانتاند داشته باشیم؟
خیر. API میتواند مستقل از رابط کاربری ساخته شود. اپلیکیشن موبایل، فرانتاند جداگانه یا سرویسهای دیگر میتوانند از آن استفاده کنند.
آیا Laravel بهصورت پیشفرض از JSON پشتیبانی میکند؟
بله. لاراول میتواند آرایهها و مدلها را به JSON تبدیل کند. همچنین با response()->json() میتوانید پاسخ JSON و کد وضعیت HTTP موردنظر را برگردانید.
تفاوت Route::resource و Route::apiResource چیست؟
Route::resource معمولاً مسیرهای مربوط به عملیات فرمهای HTML مانند create و edit را نیز ایجاد میکند. Route::apiResource این مسیرها را ایجاد نمیکند و برای عملیات معمول API مناسبتر است.
آیا برای ساخت REST API در Laravel به Sanctum نیاز داریم؟
خیر. میتوانید API عمومی بسازید که نیازی به احراز هویت نداشته باشد. اما برای APIهای خصوصی یا عملیاتی که باید فقط کاربران مشخصی به آنها دسترسی داشته باشند، باید سازوکار مناسب احراز هویت و مجوز دسترسی را پیادهسازی کنید. Sanctum یکی از گزینههای رایج در لاراول است.
آیا میتوان API را به اپلیکیشن اندروید متصل کرد؟
بله. اپلیکیشن میتواند درخواستهای HTTP را ارسال کند، پاسخ JSON را دریافت کند و اطلاعات را در رابط کاربری نمایش دهد. برای عملیات خصوصی باید احراز هویت و کنترل دسترسی نیز بهدرستی انجام شوند.
چرا API بهجای اطلاعات، خطای 404 برمیگرداند؟
ممکن است آدرس اشتباه باشد، Route تعریف نشده باشد یا منبع موردنظر در دیتابیس وجود نداشته باشد. با اجرای php artisan route:list --path=api و بررسی شناسه منبع میتوانید علت را پیدا کنید.
آیا استفاده از API Resource اجباری است؟
خیر. میتوانید مستقیماً مدل را به JSON تبدیل کنید. بااینحال، API Resource برای کنترل فیلدهای خروجی، استانداردسازی پاسخها و مستقل نگه داشتن قرارداد API از ساختار داخلی مدل مفید است.
جمعبندی
REST API یکی از بخشهای مهم توسعه نرمافزارهای مدرن است و Laravel ابزارهای مناسبی برای پیادهسازی آن در اختیار توسعهدهندگان قرار میدهد.
در این مقاله یک API ساده برای مدیریت محصولات ساختیم و با مفاهیم مهمی مانند Route، Controller، Migration، Eloquent، Validation، API Resource، کدهای وضعیت HTTP و Laravel Sanctum آشنا شدیم.
برای ساخت API در یک پروژه واقعی، تنها اجرای عملیات CRUD کافی نیست. باید اعتبارسنجی، احراز هویت، کنترل مجوز دسترسی، مدیریت خطاها، امنیت و مستندسازی را نیز در نظر بگیرید.





