راهنمای ساخت CRUD پایه برای API
در این راهنما فقط از الگوهای عمومی Laravel و Doravel استفاده میکنیم و وارد پیادهسازیهای سفارشی یک پروژه خاص نمیشویم.
این راهنما چه چیزی را پوشش میدهد؟
فرض میکنیم قرار است برای موجودیت Post این endpointها را بسازیم:
GET /api/postsPOST /api/postsGET /api/posts/{post}PUT /api/posts/{post}DELETE /api/posts/{post}
روند کار در این راهنما به این ترتیب است:
- تحلیل DB
- ساخت migration دیتابیس
- ساخت model با reliese/laravel
- آمادهسازی model
- پیکربندی Dorapi
- ساخت
FormRequest - ساخت
JsonResource - تعریف routeهای CRUD
- پیادهسازی controller و logic
پیشنیازها
قبل از شروع، بهتر است این موارد در پروژه آماده باشند:
- Doravel نصب شده باشد
- پروژه از نوع API باشد
- تنظیمات
dornica-api-kit.phpمنتشر شده باشد - ابزار تولید مدل با Reliese در پروژه فعال باشد
برای مطالعه تکمیلی:
۱. تحلیل DB
اولین مرحله کدنویسی نیست. در ابتدا باید دقیق مشخص شود چه چیزی قرار است ساخته شود.
وقتی task را تحویل میگیرید، این سؤالها را مشخص کنید:
- نام موجودیت چیست؟
- جدول دیتابیس آن وجود دارد یا نه؟
- این موجودیت چه فیلدهایی دارد؟
- کدام فیلدها در لیست نمایش داده میشوند؟
- کدام فیلدها در create و edit قابل دریافت هستند؟
- آیا relation دارد؟
- آیا نیاز به soft delete دارد؟
- آیا فیلدی مثل
is_active،sort،statusیاcreated_byدارد؟
خروجی این مرحله
در پایان این مرحله باید حداقل این تصویر اولیه روشن باشد:
| بخش | مقدار نمونه |
|---|---|
| نام موجودیت | Post |
| نام جدول | posts |
| فیلدهای اصلی | title, slug, body, is_active |
| relationها | برای نمونه author |
| فیلدهای list | title, slug, is_active, created_at |
| فیلدهای create و edit | title, slug, body, is_active |
اگر این مرحله مبهم بماند، معمولاً بقیه مراحل هم با چند بار بازنویسی، تغییر migration و اصلاح validation همراه میشوند.
۲. migration
اگر جدول هنوز وجود ندارد، در این مرحله migration آن را ایجاد کنید.
php artisan make:migration create_posts_table
نمونه:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('slug')->unique();
$table->text('body')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
در این مرحله روی این موارد حساس باشید:
- نوع هر ستون درست انتخاب شود
- unique بودن فیلدهایی مثل
slugاز همینجا مشخص شود - nullable بودن یا نبودن فیلدها روشن باشد
- اگر قرار است حذف نرم داشته باشید،
softDeletes()را اضافه کنید
اگر migration از قبل وجود داشت، migration جدید نسازید. فقط migration موجود را بخوانید و مطمئن شوید ساختار جدول با task هماهنگ است.
۳. model
بعد از مشخص شدن جدول، model را بر اساس ساختار واقعی دیتابیس بسازید. در این راهنما، مبنا استفاده از Reliese است.
پکیج مرجع:
نمونه دستور:
php artisan code:models --table=posts
این دستور معمولاً model اولیه را بر اساس ساختار جدول تولید میکند.
model فقط یک فایل ساده نیست. این فایل نقطه اتصال این بخشها است:
- جدول دیتابیس
- castها
- relationها
- رفتارهای Eloquent
اگر model از قبل وجود داشت، دوباره آن را نسازید. همان فایل موجود را بررسی و تکمیل کنید.
۴. آمادهسازی model
بعد از ساخته شدن model، کار تمام نشده است. در این مرحله باید model را برای استفاده در API و بهویژه endpoint لیست آماده کنید.
در Doravel، قابلیت Dorapi برای endpointهای list استفاده میشود.
یعنی هرجا قرار است query لیست، filter، sort، field و populate استاندارد داشته باشید، model باید از Dorapi پشتیبانی کند.
برای مطالعه کامل:
نمونه model:
<?php
namespace App\Models;
use App\Dorapi\PostDorapi;
use Dornica\APIKit\Dorapi\HasDorapi;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
use HasDorapi;
use SoftDeletes;
protected mixed $dorapi = PostDorapi::class;
protected $fillable = [
'title',
'slug',
'body',
'is_active',
];
protected $casts = [
'is_active' => 'boolean',
];
}
در این مرحله این بخشها باید کامل شوند:
HasDorapiروی model- property مربوط به
$dorapi fillablecasts- relationهای لازم، اگر وجود دارند
اگر relation دارید، آن را در model تعریف کنید.
مثلاً اگر هر Post به یک User تعلق دارد:
public function author()
{
return $this->belongsTo(User::class, 'author_id');
}
relation باید در model تعریف شده باشد تا بعداً در کلاس پیکربندی Dorapi قابل استفاده باشد.
۵. پیکربندی Dorapi
در این مرحله باید کلاس پیکربندی Dorapi را بسازید. این کلاس مشخص میکند endpoint لیست چه قرارداد و چه قابلیتهایی دارد.
میتوانید آن را با command خود Doravel بسازید:
php artisan dornica:make-dorapi Post
نمونه:
<?php
namespace App\Dorapi;
use Dornica\APIKit\Dorapi\Builders\Field;
use Dornica\APIKit\Dorapi\Builders\Relation;
use Dornica\APIKit\Dorapi\Builders\Sort;
use Dornica\APIKit\Dorapi\Dorapi;
use Dornica\APIKit\Dorapi\DorapiProperty;
use Dornica\APIKit\Dorapi\Enums\FilterOperator;
use Dornica\APIKit\Dorapi\Enums\SortDirection;
class PostDorapi extends Dorapi
{
public function fields(): Field
{
return DorapiProperty::field()
->addDefault('title')
->addDefault('slug')
->addDefault('is_active')
->addDefault('created_at')
->add('body');
}
public function relations(): Relation
{
return DorapiProperty::relation()
->add('author');
}
public function filters(): array
{
return [
DorapiProperty::filter()
->make('id')
->allowedOperators([
FilterOperator::EQUAL,
FilterOperator::IN,
]),
DorapiProperty::filter()
->make('title')
->allowedOperators([
FilterOperator::EQUAL,
FilterOperator::LIKE,
]),
DorapiProperty::filter()
->make('is_active')
->allowedOperators([
FilterOperator::EQUAL,
]),
];
}
public function sorts(): Sort
{
return DorapiProperty::sort()
->add('title')
->add('created_at')
->addDefault('id', SortDirection::DESC);
}
}
این فایل این موارد را کنترل میکند:
- fieldهای قابل انتخاب
- relationهای قابل populate
- filterهای مجاز
- sortهای مجاز
- sort پیشفرض
هر چیزی که در لیست لازم است، باید در این کلاس تعریف شود.
اگر فیلدی اینجا تعریف نشده باشد، نباید انتظار داشته باشید کاربر بتواند روی آن filter بزند، sort بزند یا آن را در fields درخواست کند.
۶. FormRequest
در این مرحله باید validation عملیات create و edit را بنویسید.
بهترین محل این کار در Laravel، FormRequest است.