Laravel 11 : Mise en Œuvre d’un CRUD Laravel avec Spatie Query Builder

Introduction

Dans cet article, nous allons construire une API CRUD (Create, Read, Update, Delete) pour gérer les entités dans une application Laravel. Nous utiliserons Spatie Query Builder pour ajouter des fonctionnalités de tri, de filtrage, et de pagination de manière simple et efficace. De plus, nous intégrerons un trait personnalisé pour simplifier la gestion des réponses API.

Spatie Query Builder est un package Laravel qui simplifie la construction de requêtes complexes en ajoutant des fonctionnalités de tri, de filtrage, et de pagination à vos API. Il permet de gérer ces aspects directement à partir des paramètres d’URL, réduisant ainsi la quantité de code SQL que vous devez écrire manuellement.

Prérequis

Avant de suivre ce tutoriel, assurez-vous d’avoir :

  • Une installation de Laravel configurée sur votre machine. Vous pouvez en créer un nouveau en suivant ce lien
  • Postman ou un client API similaire pour tester les endpoints de votre API.

Use case

Imaginons que vous êtes en train de créer une application de gestion de contenu pour un blog. Vous souhaitez permettre aux administrateurs de gérer différentes catégories de contenu, telles que “Technologie”, “Voyages”, “Cuisine”, etc. Pour atteindre cet objectif, vous devez mettre en place un système CRUD (Create, Read, Update, Delete) pour les catégories.

Laravel est un framework PHP qui vous offre toutes les fonctionnalités nécessaires pour développer des applications web robustes et bien structurées. Une fois Laravel installé, vous pourrez créer un modèle pour les catégories, ajouter les routes nécessaires pour gérer les opérations CRUD, et configurer la base de données pour stocker les informations sur les catégories.

En suivant ce guide, vous apprendrez à configurer votre projet, et à mettre en place un CRUD complet pour gérer les catégories de contenu de votre application. Cela vous permettra de créer un système flexible où les administrateurs pourront facilement ajouter, modifier, et supprimer des catégories pour organiser le contenu de manière efficace.

Activer les Routes API

Si vous développez une application qui doit communiquer avec d’autres services, comme une application mobile ou un site web, vous allez probablement utiliser une API sans état (stateless). Une API stateless ne garde pas de mémoire entre les requêtes. Chaque requête est traitée individuellement, sans se souvenir des précédentes. Cela rend votre application plus simple à gérer et plus rapide, car elle n’a pas besoin de suivre l’état de chaque utilisateur.

Pour configurer Laravel pour qu’il gère ces requêtes API de manière efficace, vous pouvez activer le routage API en utilisant une simple commande. Cette commande va préparer votre application à recevoir et traiter des requêtes API sans se soucier de l’état des utilisateurs.

Voici la commande que vous devez exécuter :

sail artisan install:api

Cette commande configure Laravel pour qu’il soit prêt à gérer des routes API. Cela inclut la création d’un fichier routes/api.php si ce n’est pas déjà fait, et l’activation de la gestion des sessions sans état pour ces routes. C’est important pour les applications qui nécessitent une API RESTful, où chaque requête est traitée indépendamment des autres.

Installer Spatie Query Builder

Pour utiliser Spatie Query Builder, vous devez l’installer via sail

sail composer require spatie/laravel-query-builder

Ce package simplifie la construction de requêtes complexes avec des fonctionnalités de tri, de filtrage, et de pagination basées sur les paramètres d’URL.

Créer le Modèle

Nous allons créer un modèle pour nos entités, accompagné d’une migration pour la table correspondante. Ce modèle comprendra les champs suivants : id, nom, et description. Lorsque vous créez un modèle avec l’option -m, Laravel génère automatiquement une migration correspondante pour ce modèle.

sail artisan make:model Category -m

Cette commande génère un fichier de migration dans le répertoire database/migrations, contenant les directives pour créer une table. Ajoutez les lignes suivantes dans ce fichier :

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id(); // Crée une colonne auto-incrémentée 'id' de type BIGINT.
        $table->string('name'); // Crée une colonne 'name' de type VARCHAR.
        $table->text('description')->nullable(); // Crée une colonne 'description' de type TEXT, qui peut être NULL.
        $table->timestamps(); // Crée les colonnes 'created_at' et 'updated_at' pour gérer les dates de création et de mise à jour.
    });
}

public function down()
{
    Schema::dropIfExists('categories'); // Supprime la table 'categories' si elle existe.
}

Laravel génère aussi une classe modèle Category dans le répertoire app/Models

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use HasFactory;

    /**
     * Les attributs qui sont assignables en masse.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'description',
    ];

    /**
     * Les attributs qui doivent être cachés pour les tableaux.
     *
     * @var array
     */
    protected $hidden = [];

    /**
     * Les attributs qui doivent être mutés en dates.
     *
     * @var array
     */
    protected $dates = ['created_at', 'updated_at'];
}

Explication des Éléments Clés

  • use HasFactory; : Ce trait permet d’utiliser les usines (factories) pour générer des instances de modèle à des fins de tests ou de seeding.
  • protected $fillable : Ce tableau définit les attributs que vous autorisez à être remplis directement lors de la création ou de la mise à jour d’un enregistrement. C’est une protection importante contre les modifications non autorisées.
  • protected $hidden : Ce tableau définit les attributs qui doivent être cachés lorsqu’un modèle est converti en tableau ou en JSON, par exemple lors d’une réponse API. Dans cet exemple, aucun attribut n’est spécifié comme caché, donc tous les attributs seront visibles.
  • protected $dates : Ce tableau indique à Eloquent quels attributs doivent être automatiquement convertis en instances de Carbon, ce qui facilite la manipulation des dates.

Les migrations:

Les migrations dans Laravel sont des fichiers PHP qui permettent de gérer la structure de votre base de données de manière versionnée. Elles agissent comme un contrôle de version pour votre base de données, vous permettant de créer, modifier ou supprimer des tables et des colonnes au fil du temps.

Pourquoi Utiliser des Migrations ?

  • Gestion du Schéma de la Base de Données : Les migrations permettent de gérer l’évolution du schéma de votre base de données (ajout de tables, modification de colonnes, suppression de tables, etc.) de manière contrôlée.
  • Versionnement : Chaque migration est horodatée, ce qui permet de retracer les modifications apportées à la base de données et de revenir à un état antérieur si nécessaire.
  • Automatisation : Les migrations rendent la création et la mise à jour des tables automatisées et reproductibles, ce qui est particulièrement utile lorsqu’il y a plusieurs environnements de développement (local, staging, production).

Les modèles

Les modèles dans Laravel sont des classes qui représentent les tables de votre base de données. Chaque modèle est lié à une table spécifique et permet d’interagir avec celle-ci de manière fluide et intuitive en utilisant l’ORM (Object-Relational Mapping) Eloquent de Laravel.

Pourquoi Utiliser des Modèles ?

  • Abstraction des Requêtes SQL : Les modèles vous permettent de manipuler les données de la base de données sans écrire directement des requêtes SQL. Par exemple, vous pouvez récupérer, créer, mettre à jour ou supprimer des enregistrements à l’aide de méthodes simples.
  • Gestion Automatique des Relations : Eloquent gère les relations entre les différentes tables, comme les relations “one to many”, “one to one”, ou “many to many”. Cela vous permet de récupérer des données liées avec une syntaxe propre et concise.
  • Sécurité et Validation : Les modèles peuvent être utilisés pour valider les données avant de les enregistrer dans la base de données, assurant ainsi l’intégrité des données.

Exécuter la migration pour créer la table categories dans notre base de données:

sail artisan migrate

Créer le Trait ApiResponser

Pour simplifier la gestion des réponses paginées et rendre le code réutilisable, nous allons créer un trait appelé ApiResponser.

Créer le fichier de trait : Créez un fichier ApiResponser.php dans le répertoire app/Traits :

mkdir app/Traits
touch app/Traits/ApiResponser.php

Implémenter le trait :

Ouvrez app/Traits/ApiResponser.php et ajoutez le code suivant :

namespace App\Traits;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\QueryBuilder;
use Illuminate\Support\Facades\Log;

trait ApiResponser
{
    public function paginateResponse(Request $request, $model, $resource, $allowedFilters = [], $allowedSorts = [], $perPage = 15): JsonResponse
    {
        $query = QueryBuilder::for($model)
            ->allowedFilters($allowedFilters)
            ->allowedSorts($allowedSorts)
            ->paginate($request->input('per_page', $perPage));

        Log::info($query->toSql()); // Débogage : afficher la requête SQL générée

        return response()->json([
            'data' => $resource::collection($query->items()),
            'meta' => [
                'total' => $query->total(),
                'count' => $query->count(),
                'per_page' => $query->perPage(),
                'current_page' => $query->currentPage(),
                'total_pages' => $query->lastPage(),
                'links' => [
                    'first' => $query->url(1),
                    'last' => $query->url($query->lastPage()),
                    'prev' => $query->previousPageUrl(),
                    'next' => $query->nextPageUrl(),
                ],
            ],
        ]);
    }
}

Créer le Contrôleur

Nous allons maintenant créer un contrôleur pour gérer les opérations CRUD sur les catégories, en utilisant Spatie Query Builder et le trait ApiResponser.

Créer le contrôleur :

sail artisan make:controller CategoryController

Ajouter les méthodes CRUD :

Ouvrez le fichier app/Http/Controllers/CategoryController.php. Vous y verrez que les méthodes index, store, show, update, et destroy ont été automatiquement créées lorsque le contrôleur a été généré. Maintenant que ces méthodes sont prêtes, il ne vous reste plus qu’à les compléter en ajoutant le code nécessaire pour gérer les opérations CRUD (Create, Read, Update, Destroy).

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\QueryBuilder;
use App\Http\Resources\CategoryResource;
use App\Traits.ApiResponser;

class CategoryController extends Controller
{
    use ApiResponser;

    public function index(Request $request)
    {
        return $this->paginateResponse(
            $request,
            Category::class,
            CategoryResource::class,
            ['name'], // Filtres autorisés
            ['name', 'created_at'] // Champs autorisés pour le tri
        );
    }

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

        $category = Category::create($validated);

        return new CategoryResource($category);
    }

    public function show(Category $category)
    {
        return new CategoryResource($category);
    }

    public function update(Request $request, Category $category)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
        ]);

        $category->update($validated);

        return new CategoryResource($category);
    }

    public function destroy(Category $category)
    {
        $category->delete();

        return response()->json(null, 204);
    }
}

Créer une Resource API

Dans cette étape, nous allons créer une Resource API. Une ressource API dans Laravel permet de transformer vos modèles et les données associées en un format approprié pour les réponses JSON. Cela est particulièrement utile lorsque vous travaillez avec des API RESTful, car cela vous permet de contrôler et de structurer exactement ce que vous envoyez au client.

Pourquoi Utiliser une Resource API ?

  • Contrôle de la Structure des Réponses : Les resources API vous permettent de définir précisément quelles données sont renvoyées dans les réponses JSON. Cela signifie que vous pouvez inclure uniquement les champs nécessaires et omettre les données sensibles ou inutiles.
  • Consistance des Réponses : En utilisant des ressources API, vous vous assurez que les réponses de votre API sont formatées de manière cohérente à travers toute votre application.
  • Facilité d’Extension : Si vous avez besoin d’ajouter des données supplémentaires à une réponse, comme des attributs calculés ou des relations avec d’autres modèles, vous pouvez facilement le faire dans la resource.

Pour créer une resource API dans Laravel, vous pouvez utiliser la commande Artisan suivante :

sail artisan make:resource CategoryResource

Cette commande génère un fichier dans le répertoire app/Http/Resources. Ce fichier contient une méthode toArray où vous pouvez définir comment transformer le modèle en un tableau

Ouvrez app/Http/Resources/CategoryResource.php et définissez le format de la réponse JSON :

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CategoryResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'created_at' => $this->created_at->toDateTimeString(),
            'updated_at' => $this->updated_at->toDateTimeString(),
        ];
    }
}

Ajouter des Routes API

Nous allons maintenant enregistrer les routes pour notre API CRUD.

Ouvrez routes/api.php et ajoutez les routes :

use App\Http\Controllers\CategoryController;

Route::apiResource('categories', CategoryController::class);

Cela définira automatiquement les routes pour les méthodes index, store, show, update, et destroy dans votre contrôleur CategoryController.

Explication : L’API Resource de Laravel génère automatiquement les routes RESTful standard pour un contrôleur donné. Ces routes ne sont pas directement liées au nom des méthodes présentes dans le contrôleur. Au lieu de cela, Laravel associe chaque route à une action spécifique, en fonction des conventions REST.

Par exemple :

  • GET /categories : Appelle la méthode index pour lister toutes les catégories.
  • POST /categories : Appelle la méthode store pour créer une nouvelle catégorie.
  • GET /categories/{id} : Appelle la méthode show pour afficher une catégorie spécifique.
  • PUT/PATCH /categories/{id} : Appelle la méthode update pour mettre à jour une catégorie spécifique.
  • DELETE /categories/{id} : Appelle la méthode destroy pour supprimer une catégorie spécifique.

Laravel suit ces conventions pour définir les routes, et c’est à vous de vous assurer que les méthodes correspondantes sont présentes dans le contrôleur pour que les routes fonctionnent correctement.

Trier et filtrer avec Spatie Query Builder

Grâce à Spatie Query Builder et au trait ApiResponser, vous pouvez facilement ajouter des fonctionnalités de tri, de filtrage et de pagination à votre API.

Tout d’abord, assurez-vous que les routes API ont bien été générées en tapant la commande suivante dans votre terminal :

sail artisan route:list

Cette commande affichera la liste des routes disponibles dans votre application Laravel, comme montré dans la capture d’écran ci-dessous. Vous verrez les méthodes HTTP associées (GET, POST, PUT/PATCH, DELETE) et les URI correspondants (par exemple, api/categories, api/categories/{category}).

Tri (Sorting) :

Trier par nom de catégorie en ordre croissant :

GET http://localhost/api/categories?sort=name

Trier par nom de catégorie en ordre décroissant :

GET http://localhost/api/categories?sort=-name

Trier par date de création en ordre croissant

GET http://localhost/api/categories?sort=created_at

Trier par date de création en ordre décroissant

GET http://localhost/api/categories?sort=-created_at

Filtrage (Filtering) :

Filtrer les catégories dont le nom contient “électronique” :

GET http://localhost/api/categories?filter[name]=électronique

Filtrer les catégories avec une description spécifique

GET http://localhost/api/categories?filter[description]=High quality

Pagination :

Afficher la première page avec 10 résultats par page :

GET http://localhost/api/categories?page=1&per_page=10

Afficher la deuxième page avec 15 résultats par page :

GET http://localhost/api/categories?page=2&per_page=15

Combinaison de tri, filtrage et pagination :

Filtrer les catégories dont le nom contient “body”, trier par date de création en ordre décroissant, et afficher la première page avec 5 résultats par page :

GET http://localhost/api/categories?filter[name]=body&sort=-created_at&page=1&per_page=5

Tests des API avec Postman

Nous allons maintenant tester les différentes API liées aux catégories. En utilisant Postman, nous allons vérifier que chaque point de terminaison (endpoint) fonctionne correctement et retourne les réponses attendues.

Conclusion

Nous avons parcouru toutes les étapes nécessaires pour créer un CRUD complet avec Laravel, depuis la configuration du modèle jusqu’à l’ajout des routes et la gestion des interactions avec la base de données via des contrôleurs. Grâce à l’utilisation de Laravel et de Spatie Query Builder, nous avons pu simplifier le tri, le filtrage et la pagination de nos données, rendant notre API plus flexible et puissante. En ajoutant Adminer à notre environnement Docker, nous disposons également d’un outil convivial pour gérer nos bases de données. Avec ces compétences, vous êtes désormais capable de créer des applications robustes et bien structurées avec Laravel.

Développeuse web full-stack * Plus de publications

Développeuse Fullstack passionnée par le code, je suis diplômée en Programmation/Développement informatique de Sup’Info. Maîtrisant des langages comme PHP, JAVA et C++, je m’adapte facilement à différents environnements techniques. Mon parcours m'a permis de travailler sur une variété de projets, allant du développement Web et mobile à la création d'API et d'applications monétiques pour TPE. J'ai également une bonne connaissance de frameworks tels que Laravel, Tailwind CSS, Spring Boot et React Native.

0 0 votes
Évaluation de l'article
guest
0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires

Ingénierie informatique (SSII)

Applize crée des logiciels métiers pour accompagner les entreprises dans la transition vers le zéro papier.


Avez-vous un projet en tête ? Discutons-en.