ANUPET ACADEMY رجوع للموقع

أول API بلارافيل: من الصفر لـ endpoint شغّال

خطوة بخطوة: مشروع جديد، جدول، موديل، راوت، تحقق من المدخلات، ورد JSON محترم — وتجربة كل ده بـ curl من غير أي أداة زيادة.

أول API بلارافيل: من الصفر لـ endpoint شغّال

أغلب الناس بتتعلم لارافيل بتفضل تلف في الفيديوهات لحد ما توصل لنقطة إن عندهم مشروع شغال بس مش فاهمين الطلب بيمشي إزاي من أول ما يوصل السيرفر لحد ما يرجع JSON. المقال ده بيمشي المسار ده كامل مرة واحدة، بأصغر مثال حقيقي: API لملاحظات. هتكتب كل سطر بنفسك، وهتجرّب كل خطوة قبل ما تعدّي اللي بعدها.

المطلوب قبل ما تبدأ: PHP 8.2 على الأقل، وComposer، وقاعدة بيانات شغالة. وخلاص.

1. مشروع جديد وملف الراوتات

composer create-project laravel/laravel notes-api
cd notes-api
php artisan install:api

السطر التالت ده مهم جدًا ومش كل الشروحات بتقوله: من لارافيل 11، ملف routes/api.php مش موجود افتراضيًا في المشروع الجديد. الأمر install:api هو اللي بينشئه ويسجّله ويثبّت Sanctum معاه. لو انت بتتفرّج على شرح قديم وبيقول لك افتح routes/api.php على طول وانت ملقتهوش — دي هي.

كل راوت هتكتبه في الملف ده بياخد البادئة /api تلقائيًا. يعني notes هتبقى /api/notes.

2. الجدول والموديل

php artisan make:model Note -m

الفلاج -m بيعمل الهجرة مع الموديل. افتح ملف الهجرة الجديد في database/migrations واكتب:

public function up(): void
{
    Schema::create('notes', function (Blueprint $table) {
        $table->id();
        $table->string('title', 120);
        $table->text('body');
        $table->boolean('done')->default(false);
        $table->timestamps();
    });
}

وفي app/Models/Note.php:

class Note extends Model
{
    protected $fillable = ['title', 'body', 'done'];

    protected function casts(): array
    {
        return ['done' => 'boolean'];
    }
}

$fillable مش تفصيلة شكلية. من غيرها لارافيل هيرفض Note::create() تمامًا — وده مقصود، عشان محدش يبعت لك حقل في الريكوست مالوش لازمة ويكتبه في الجدول. القاعدة: اكتب الأعمدة اللي المستخدم مسموح له يبعتها، وبس.

بعدها:

php artisan migrate

3. التحقق من المدخلات في مكانه الصح

الغلطة اللي بشوفها كل دفعة هي إن التحقق بيتكتب جوه الكنترولر في if ورا if. لارافيل عنده مكان مخصص لده:

php artisan make:request StoreNoteRequest
class StoreNoteRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;   // مافيش صلاحيات لسه — بس خلي بالك إنها هنا
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:120'],
            'body'  => ['required', 'string'],
            'done'  => ['sometimes', 'boolean'],
        ];
    }
}

خد بالك من authorize(). لو رجّعت false هتاخد 403 على طول ومش هتفهم انت جاي منين، ودي ساعة ضايعة بتتكرر مع كل مبتدئ.

4. شكل الرد

ماترجّعش الموديل زي ما هو. الموديل بيتغيّر مع الوقت والأعمدة بتزيد، ولو رجعته مباشرة يبقى أي عمود جديد بيتسرّب للـ API — وممكن يكون عمود مش المفروض حد يشوفه.

php artisan make:resource NoteResource
class NoteResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id'         => $this->id,
            'title'      => $this->title,
            'body'       => $this->body,
            'done'       => $this->done,
            'created_at' => $this->created_at->toIso8601String(),
        ];
    }
}

دلوقتي انت اللي بتقرّر الـ API بيقول إيه، مش الجدول.

5. الكنترولر

php artisan make:controller Api/NoteController --api
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreNoteRequest;
use App\Http\Resources\NoteResource;
use App\Models\Note;

class NoteController extends Controller
{
    public function index()
    {
        return NoteResource::collection(
            Note::latest()->paginate(15)
        );
    }

    public function store(StoreNoteRequest $request)
    {
        $note = Note::create($request->validated());

        return NoteResource::make($note)
            ->response()
            ->setStatusCode(201);
    }

    public function show(Note $note)
    {
        return NoteResource::make($note);
    }
}

تلات حاجات هنا تستاهل تقف عندها:

  • StoreNoteRequest مكتوب كنوع للمعامل، فلارافيل بيشغّل التحقق قبل ما يدخل جسم الدالة أصلًا. لو المدخلات غلط، الكود ده مابيتنفّذش.
  • $request->validated() بترجّع الحقول اللي عدّت التحقق بس — مش كل اللي المستخدم بعته. الفرق بينها وبين $request->all() هو الفرق بين API آمن وواحد لأ.
  • show(Note $note) — لارافيل بيجيب السطر من قاعدة البيانات بنفسه من الرقم اللي في الرابط، وبيرجّع 404 لوحده لو مالقهوش.

6. الراوتات

في routes/api.php:

use App\Http\Controllers\Api\NoteController;

Route::apiResource('notes', NoteController::class);

سطر واحد عمل خمس راوتات. اتأكد بنفسك:

php artisan route:list --path=api

7. جرّبه

php artisan serve
curl -X POST http://127.0.0.1:8000/api/notes \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"title":"مراجعة الاستعلامات","body":"أراجع صفحة الكورسات قبل السيشن"}'

المفروض ترجع 201 ومعاها الملاحظة. جرّب دلوقتي تبعت طلب ناقص:

curl -X POST http://127.0.0.1:8000/api/notes \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"title":""}'

هتاخد 422 ومعاها message وerrors فيها كل حقل وغلطته. ترويسة Accept: application/json دي هي الفرق: من غيرها لارافيل بيفترض إنك متصفح، وبيعمل إعادة توجيه بدل ما يرد JSON — وده سبب سؤال «ليه بيرجع لي HTML؟» اللي بيتسأل ألف مرة.

8. أخطاء بتتكرر — خد بالك منها من دلوقتي

  • ماتحطش منطق الشغل في الكنترولر. الكنترولر بياخد الطلب ويسلّم ويرجّع الرد. لما المنطق يكبر، انقله لكلاس خدمة.
  • رقّم النتائج من أول يوم. Note::all() شغالة على عشرين سطر عندك، وهتقع على خمسين ألف سطر في الإنتاج.
  • رجّع كود الحالة الصح. 201 للإنشاء، 422 للتحقق، 404 لغير موجود، 401 لغير مسجّل دخول. العميل اللي هيستهلك الـ API بيبني عليها.
  • ماتنساش الفهارس على الأعمدة اللي بتبحث بيها — وده موضوع لوحده اتكلمنا فيه في [Eloquent: إزاي تكتب استعلامات مش هتوقّع السيرفر](/blog/eloquent-n-plus-one).

الخطوة الجاية

عندك دلوقتي API شغال. الحاجة اللي المفروض تعملها النهاردة قبل ما تقفل الجهاز: ضيف update وdestroy بنفسك من غير ما ترجع للمقال، وبعدها اربطه بمصادقة Sanctum عشان الملاحظات تبقى لكل مستخدم لوحده.

إحنا في أكاديمية أنوبت بنمشي المسار ده بالترتيب: PHP خام وSQL خام الأول في [كورس الباك إند](/courses/back-end)، وبعدها لارافيل — عشان لما تشوف apiResource بيعمل خمس راوتات في سطر، تكون عارف الخمسة دول كانوا هيبقوا شكلهم إيه لو كتبتهم بإيدك.

الكلمات المفتاحية laravel api عمل api بلارافيل تعلم لارافيل laravel rest api شرح php artisan install:api شرح api بالعربي

كل المقالات