Chapitre 13Projet SunuLearn

API REST — les endpoints JSON

Routes API, Resources et authentification Sanctum

Concepts Théoriques

Jusqu'ici, SunuLearn retourne du HTML (Blade). Mais une future application mobile ou un frontend React aura besoin de données brutes en JSON. C'est le rôle d'une API REST — des endpoints qui retournent des données structurées au lieu de pages HTML.

routes/api.php

Les routes API vivent dans un fichier séparé. Elles ont automatiquement le préfixe /api/ :

// routes/api.php
Route::get('/formations', [ApiFormationController::class, 'index']);
// Accessible à : http://localhost:8000/api/formations

Les routes API n'ont pas de sessions ni de CSRF — elles utilisent des tokens pour l'authentification.

API Resource — formater le JSON

Retourner Formation::all() expose TOUTES les colonnes, y compris les timestamps et les champs internes. Une API Resource formate la réponse :

php artisan make:resource FormationResource
// app/Http/Resources/FormationResource.php
class FormationResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'slug' => $this->slug,
            'description' => $this->short_description,
            'level' => $this->level,
            'duration' => $this->duration,
            'chapters_count' => $this->chapters_count,
            'is_free' => $this->is_free,
            'category' => $this->whenLoaded('category', fn () => [
                'name' => $this->category->name,
                'slug' => $this->category->slug,
            ]),
            'image_url' => $this->image_path ? asset('storage/' . $this->image_path) : null,
        ];
    }
}

Usage dans le contrôleur :

return FormationResource::collection(Formation::published()->with('category')->paginate(12));

Le JSON retourné est propre, paginé, et ne contient que les données nécessaires.

Sanctum — authentification API

Laravel Sanctum gère l'authentification par token pour les API :

php artisan install:api
// routes/api.php
Route::post('/login', function (Request $request) {
    $credentials = $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    if (!Auth::attempt($credentials)) {
        return response()->json(['message' => 'Identifiants invalides'], 401);
    }

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

    return response()->json(['token' => $token, 'user' => $request->user()]);
});

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn (Request $request) => $request->user());
    Route::post('/formations/{formation}/enroll', [ApiEnrollmentController::class, 'store']);
});

Le client envoie le token dans le header : Authorization: Bearer {token}.