آموزش لاراول ۱۲ – قسمت هشتم: ساخت API در لاراول

سلام من آرش فدائی هستم و تو این قسمت از سری آموزشی لاراول ۱۲ قراره درباره ساخت API صحبت کنیم. APIها به اپلیکیشن‌تون اجازه می‌دن با برنامه‌های دیگه (مثل اپ‌های موبایل یا فرانت‌اندهای جداگونه) ارتباط برقرار کنن. لاراول ابزارهای فوق‌العاده‌ای برای ساخت APIهای امن و کارآمد داره. تو این مقاله، یاد می‌گیرید چطور یه API ساده برای مدیریت پست‌ها بسازید، احراز هویت API رو پیاده کنید و یه سری نکات پیشرفته رو بررسی کنید. بریم شروع کنیم!

API در لاراول: تجربه شخصی من

اولین باری که خواستم یه API بسازم، داشتم برای یه اپلیکیشن موبایل بک‌اند درست می‌کردم. فکر می‌کردم قراره کلی کد پیچیده بنویسم، اما لاراول با ابزارهایی مثل Resource Routes و API Authentication این کار رو برام خیلی راحت کرد. یه بار به اشتباه مسیرهای API رو بدون احراز هویت باز گذاشتم و کلی داده غیرمجاز درز کرد! تو لاراول ۱۲، ابزارهای API حتی قوی‌تر شدن و قابلیت‌هایی مثل بهبودهای امنیتی و بهینه‌سازی‌های پاسخ‌دهی اضافه شده. حالا بیاید با یه مثال عملی وارد بشیم!

پیش‌نیازها

قبل از شروع، مطمئن بشید که:

  • پروژه لاراول‌تون درست تنظیم شده (مثل قسمت اول).

  • مدل Post و جدول posts رو از قسمت سوم دارید.

  • سیستم احراز هویت (مثل چیزی که تو قسمت پنجم با Breeze نصب کردیم) فعاله.

  • یه ابزار مثل Postman یا cURL برای تست API دارید.

ما تو این آموزش یه API برای مدیریت پست‌ها می‌سازیم.

ساخت مسیرهای API

لاراول مسیرهای API رو تو فایل routes/api.php مدیریت می‌کنه. بیاید یه Resource Route برای پست‌ها تعریف کنیم:

use App\Http\Controllers\Api\PostController;

Route::apiResource('posts', PostController::class);

این کد یه سری مسیر API برای عملیات CRUD روی پست‌ها می‌سازه:

  • GET /api/posts → لیست پست‌ها

  • GET /api/posts/{id} → نمایش یه پست

  • POST /api/posts → ایجاد پست

  • PUT/PATCH /api/posts/{id} → به‌روزرسانی پست

  • DELETE /api/posts/{id} → حذف پست

برای دیدن همه مسیرها، این دستور رو اجرا کنید:

php artisan route:list --path=api

یه تجربه از خودم: یه بار مسیرهای API رو با مسیرهای وب قاطی کردم و کلی گیج شدم که چرا پاسخ‌ها به صورت JSON برنمی‌گردن. همیشه مسیرهای API رو تو api.php نگه دارید!

ساخت کنترلر API

بیاید یه کنترلر برای API بسازیم:

php artisan make:controller Api/PostController --api --model=Post

این دستور یه کنترلر با متدهای CRUD آماده تو app/Http/Controllers/Api/PostController.php می‌سازه. بیاید متد index رو اصلاح کنیم تا پست‌ها رو به صورت JSON برگردونه:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return response()->json($posts);
    }
}

حالا اگه به http://localhost:8000/api/posts درخواست GET بفرستید (مثلاً با Postman)، یه آرایه JSON از پست‌ها می‌گیرید. من تو یه پروژه داشتم API برای یه اپ موبایل می‌ساختم و این روش برای برگردوندن داده‌ها خیلی سریع و تمیز بود.

استفاده از Resource برای فرمت‌دهی پاسخ‌ها

برای اینکه پاسخ‌های API مرتب‌تر و حرفه‌ای‌تر باشن، از API Resources استفاده می‌کنیم. یه Resource بسازید:

php artisan make:resource PostResource

فایل app/Http/Resources/PostResource.php رو اینجوری اصلاح کنید:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
            'created_at' => $this->created_at->toDateTimeString(),
        ];
    }
}

حالا متد index تو PostController رو اینجوری تغییر بدید:

public function index()
{
    $posts = Post::all();
    return PostResource::collection($posts);
}

و برای متد show:

public function show(Post $post)
{
    return new PostResource($post);
}

اینجا PostResource داده‌ها رو به فرمت JSON مرتب برمی‌گردونه. یه تجربه از خودم: یه بار فراموش کردم Resource رو درست تنظیم کنم و داده‌های اضافی (مثل کلیدهای داخلی دیتابیس) تو API برگشت. همیشه از Resource برای کنترل خروجی استفاده کنید!

احراز هویت در API

برای محافظت از مسیرهای API، از Sanctum (یه پکیج احراز هویت API تو لاراول) استفاده می‌کنیم. اول Sanctum رو نصب کنید:

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

تو فایل config/auth.php مطمئن شید که گارد sanctum فعاله:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'sanctum',
        'provider' => 'users',
    ],
],

حالا مسیرهای API رو با middleware auth:sanctum محافظت کنید:

Route::apiResource('posts', PostController::class)->middleware('auth:sanctum');

برای تست، باید یه توکن API برای کاربر بسازید. تو یه کنترلر (مثلاً app/Http/Controllers/Auth/RegisteredUserController.php) می‌تونید بعد از ثبت‌نام توکن بسازید:

protected function create(array $data)
{
    $user = User::create([
        'full_name' => $data['full_name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);

    $token = $user->createToken('api-token')->plainTextToken;

    return $user;
}

حالا کاربر می‌تونه با این توکن درخواست‌های API رو بفرسته. تو Postman، توکن رو تو هدر Authorization به این شکل اضافه کنید:

Authorization: Bearer <your-token>

یه تجربه از خودم: یه بار توکن رو اشتباه تو هدر گذاشتم و کلی خطای 401 گرفتم. همیشه مطمئن شید توکن درست فرمت شده!

افزودن پست از طریق API

بیاید متد store رو تو PostController تنظیم کنیم:

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|string|max:255',
        'content' => 'required|string',
    ]);

    $post = Post::create([
        'title' => $request->title,
        'content' => $request->content,
    ]);

    return new PostResource($post);
}

حالا با یه درخواست POST به http://localhost:8000/api/posts (با توکن در هدر) می‌تونید پست جدید بسازید. من تو یه پروژه داشتم API برای یه اپ موبایل می‌ساختم و این روش برای مدیریت درخواست‌های CRUD خیلی به کارم اومد.

نکات تکمیلی

  • Rate Limiting: برای جلوگیری از سوءاستفاده، می‌تونید محدودیت تعداد درخواست‌ها رو فعال کنید. تو فایل routes/api.php:

Route::apiResource('posts', PostController::class)->middleware(['auth:sanctum', 'throttle:60,1']);

اینجا throttle:60,1 یعنی حداکثر 60 درخواست در دقیقه.

  • اشکال‌زدایی: اگه API کار نکرد، از dd($request->all()) یا Postman برای چک کردن درخواست‌ها استفاده کنید. من خودم بارها با این روش مشکلاتم رو پیدا کردم.

  • لاراول ۱۲ و بهبودها: تو نسخه ۱۲، APIها با بهینه‌سازی‌های جدید مثل کش پاسخ‌ها و ابزارهای دیباگ بهتر شدن.

قسمت بعدی قراره درباره تست‌نویسی (Testing) صحبت کنیم که چطور می‌تونید مطمئن شید کدتون درست کار می‌کنه. اگه سوالی دارید یا جایی گیر کردید، تو کامنت‌ها بپرسید. من همیشه از بازخوردهای شما کلی چیز جدید یاد می‌گیرم!

تا قسمت بعدی، موفق باشید!