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 deCarbon
, 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 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.