Les API REST sont aujourd’hui des outils incontournables dans le domaine des applications web. On les utilise pratiquement pour tout ! La plus part des applications mobiles, qui fournissent des services distribués, utilisent des API REST.
Une API ou interface de programmation d’application, selon le site de redhat, est un ensemble de définitions et de protocoles qui facilite la création et l’intégration des applications. Les API permettent à deux systèmes hétérogènes de communiquer sans se soucier des technologies utilisées pour concevoir ces systèmes.
Alors les amis, je suis content de vous retrouver dans ce nouvel article pour vous parler des API. Dans cet article, nous utiliserons le framework Laravel pour concevoir une API REST. Nous allons concevoir une API pour gérer une petite bibliothèque. Nous allons l’appeler Bibliotheca.
Bon, puisque tout est dit, commençons sans plus tarder…
Création du projet
Pour commencer, nous allons créer un projet Laravel. Bien-sûr, je part du principe que nous avons tous un environnement de développement installé et bien configuré 🙃. Pas de panique ! Si ce n’est pas encore le cas, vous pouvez le faire en suivant cet article…
laravel new bibliotheca
Rien de bien compliqué jusque là 😅.
Une fois le projet initialisé, vous pouvez l’ouvrir avec votre éditeur préféré. Dans ce tutoriel, nous aurons besoin de sauvegarder des données dans une base de données. Nous utiliserons alors mysql comme SGBD (système de gestion de base de données). Cependant sentez-vous libre d’utiliser le SGBD avec lequel vous vous sentez à l’aise. Mais, dans ce cours nous nous intéresserons seulement à la configuration du projet avec le SGBD mysql.
Bien, voyons ensemble le contenu du dossier du projet.
Configuration de la base de données
Configuration du projet
Pour configurer notre projet afin que notre application puisse se connecter à une base de données, nous allons ouvrir le fichier .env dans l’éditeur de text. Ensuite il va falloir modifier les paramètres suivants :
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=bibliotheca_api
DB_USERNAME=nom_utilisateur_base_de_donees
DB_PASSWORD=mot_de_passe
- DB_DATABASE désigne le nom de la base de données.
- DB_USERNAME désigne le nom d’utilisateur de base données
- DB_PASSWORD désigne le mot de passe de l’utilisateur de base de données
Création de la base de données
Nous procédons maintenant à la création de la base de données bibliotheca_api. Vous pouvez utiliser WAMP, XAMPP ou MAMP qui vous permettrons d’installer mysql et PHPMYADMIN. Une fois installé, vous pouvez le démarrer puis lancer, dans un navigateur, la page http://localhost/phpMyAdmin.
Vous tomberez normalement sur cette page web.
Dans l’onglet Databases, nous allons renseigner le nom (bibliotheca_api) de la base de données puis sélectionner utf8_general_ci dans le champs déroulant suivant. Appuyez ensuite sur le bouton Créer.
Voilà, notre base de données a été créée et notre projet a bien été configuré pour que notre application puis y accéder. Passons maintenant à la création des tables de notre base de données.
Création des tables de la base de données
Vu d’ensemble sur la base de données
Nous allons utiliser les migrations de Laravel pour créer ces tables. Mais avant, jetons un oeil sur la structure de notre base de données.
Création des fichiers de migration
Nous allons ouvrir un terminal (se rendre dans le dossier du projet) et créer les fichiers de migration de chaque table de notre base de données avec la commande suivante :
php artisan make:migration nom_de_migration
Création de la table des catégories
php artisan make:migration create_categorie_table
Création de la table des auteurs
php artisan make:migration create_auteur_table
Création de la table des livres
php artisan make:migration create_livre_table
Vous devriez avoir maintenant, dans le dossier migrations (database > migrations) les fichiers de migration que nous avons générés (les trois derniers fichiers normalement).
Dans ce fichier nous allons déclarer les champs de nos tables, tels que le montre le modèle conceptuel de données ci-dessus.
Configuration des fichiers de migration
Dans la méthode up() de chaque fichier, nous allons y ajouté tous les champs de nos tables.
Table categorie
...
public function up()
{
Schema::create('categorie', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string("libelle");
});
}
...
Nous y avons ajouté le champs libelle à la table catégorie.
Table auteur
public function up()
{
Schema::create('auteur', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string("nom");
$table->string("prenom");
$table->string("email");
});
}
Table livre
public function up()
{
Schema::create('livre', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->string("libelle");
$table->string("description");
$table->integer("nb_page")->default(0);
$table->string("image");
$table->integer('categorie_id');
$table->integer('auteur_id');
});
}
Exécution des migrations
Nous avons fini de configurer les fichiers de migration. Maintenant, nous devons appliquer ces changements à notre base de données. Pour le faire, nous allons exécuter la commande suivante :
php artisan migrate
Après l’exécution de la commande, nous pouvons voir que notre base de données a été correctement configurée
Création des modèles
Nous passons maintenant à la création des modèles de notre application. Les modèles sont des classes un peu spéciales qui nous permettrons d’interagir avec les tables de notre base de données. Ainsi nous devons créer autant de modèle qu’il y a de tables dans notre base de données. Nous allons dans cette partie, créer les modèles de chacune des tables de notre base de données.
Le modèle categorie
php artisan make:model Categorie
Le modèle auteur
php artisan make:model Auteur
Le modèle livre
php artisan make:model Livre
Après l’exécution de ces différentes commandes, vous pourrez voir que trois nouveaux fichiers ont été créés dans le dossier Models (app > Models).
Configuration des modèles
Procédons à quelques petits réglages pour terminer la création des modèles. Nous allons ajouter un attribut $fillable dans chaque modèle. Comme suit.
Categorie
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Categorie extends Model
{
use HasFactory;
protected $fillable = ['libelle', 'created_at', 'updated_at'];
}
Auteur
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Auteur extends Model
{
use HasFactory;
protected $fillable = ['nom', 'prenom', 'email', 'created_at', 'updated_at'];
}
Livre
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Livre extends Model
{
use HasFactory;
protected $fillable = [
'commentaire', 'contactAuteur','note', 'version','active', 'user_create','user_update','etablissement_id', 'created_at', 'updated_at'
];
}
L’ajout de cet attribut avec comme valeur un tableau de la liste des noms des champs de chaque table permet de dire au framework que nous allons renseigner ces champs pour alimenter notre table.
Les contrôleurs web
Les contrôleurs sont des classes qui contiennent des méthodes qui implémenterons les actions possibles pour chaque modèle. Nous pourrons grâce à eux effectuer des insertions, modifications etc. dans la base de données. C’est cette unité de traitement qui sera chargée d’effectuer les traitements demandés après la réception des requêtes http qui seront émises par des clients web. Là encore, nous allons créer un contrôleur pour chaque model. Pour créer un contrôleur en Laravel, nous utiliserons encore une commande.
php artisan make:controller nom_controller
Les contrôleurs sont sauvegardés dans le dossier Controllers (app > Http > Controllers).
Contrôleur categorie
php artisan make:controller CategorieController
Dans le fichier créé, nous allons ajouter des méthodes pour afficher, insérer, modifier et supprimer une catégorie dans la base de données.
<?php
namespace App\Http\Controllers;
use App\Models\Categorie;
use Illuminate\Http\Request;
class CategorieController extends Controller
{
public function getAll()
{
$data = Categorie::all();
return $data;
}
public function create(Request $request)
{
if (isset($request->libelle)) {
$cat = new Categorie();
$cat->libelle = $request->libelle;
$cat->save();
return $cat;
}
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
public function update(Request $request)
{
$reponse = null;
$id = $request->id;
$libelle = $request->libelle;
if (isset($id) and isset($libelle)) {
$cat = Categorie::find($id);
if ($cat != null) {
$cat->libelle = $libelle;
$cat->save();
return $cat;
} else {
$reponse["message"] = "Catégorie introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
}
public function delete($id)
{
if (isset($id)) {
$cat = Categorie::find($id);
if ($cat != null) {
$cat->delete();
$reponse["message"] = "Supprimé avec succès.";
return $reponse;
} else {
$reponse["message"] = "Catégorie introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez préciser un identifiant SVP.";
return $reponse;
}
}
}
Prenons un peu de temps pour expliquer ce que nous faisons dans les différentes méthodes de ce contrôleur. NB: Notez aussi que ce processus est le même dans les autres contrôleurs.
La méthode getAll()
Dans cette méthode, nous avons fais une requête dans la table categorie pour récupérer toutes les catégories. Ensuite, on renvoie le résultat obtenu.
...
public function getAll()
{
$data = Categorie::all(); //Récupération de toutes la catégories.
return $data; //Envoie des catégories trouvées en base.
}
...
La méthodes create()
On utilise create() pour créer une catégorie. Les données doivent être envoyé en Json dans le corps de la requête en précisant le champs libelle et sa valeur. Je vous montre un exemple avec le logiciel POSTMAN (un outil pour tester des API REST).
Revenons maintenant dans le code.
...
public function create(Request $request)
{
if (isset($request->libelle)) {
$cat = new Categorie();
$cat->libelle = $request->libelle;
$cat->save();
return $cat;
}
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
...
Dans ce code, nous vérifions si le champ libelle a bien été fourni dans le corps de la requête avec la fonction isset (ligne 4). Si le champ est renseigné, on créé un objet catégorie, on lui passe le libellé et on sauvegarde cet objet avec la méthode save(). Enfin, on renvoie l’objet créé.
La méthode update()
Cette méthode nous permet d’appliquer une modification sur une catégorie.
public function update(Request $request)
{
$reponse = null;
$id = $request->id;
$libelle = $request->libelle;
//On vérifie si l'id et le libellé on été renseignés
if (isset($id) and isset($libelle)) {
//On recherche la catégorie avec l'identifiant fourni
$cat = Categorie::find($id);
if ($cat != null) {
//Si la catégorie existe, on met à jour son libellé
$cat->libelle = $libelle;
//on savegarde la modification
$cat->save();
return $cat;
} else {
$reponse["message"] = "Catégorie introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
}
Ici, on s’attend à un identifiant (l’identifiant de la catégorie à modifier) et le nouveau libellé à enregistrer. On s’assure donc que ces champs sont bien renseignés. Si oui, on fait la modification puis on sauvegarde la catégorie en base. Si toutes ces conditions ne sont pas remplies, on renvoie un message d’erreur à l’utilisateur à chaque fois.
La méthode delete()
Pour la méthode delete(), il faut préciser l’identifiant de la catégorie à supprimer. On vérifie ensuite que la catégorie existe bien en base. Si elle existe, on la supprime avec la méthode delete().
public function delete($id)
{
if (isset($id)) {
$cat = Categorie::find($id);
if ($cat != null) {
$cat->delete();
$reponse["message"] = "Supprimé avec succès.";
return $reponse;
} else {
$reponse["message"] = "Catégorie introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez préciser un identifiant SVP.";
return $reponse;
}
}
Voilà ! Pour le reste, il s’agira de suivre la même logique en adaptant le code selon le cas.
Contrôleur auteur
php artisan make:controller AuteurController
Dans le fichier créé, nous allons ajouter des méthodes pour afficher, insérer, modifier et supprimer un auteur dans la base de données.
<?php
namespace App\Http\Controllers;
use App\Models\Auteur;
use Illuminate\Http\Request;
class AuteurController extends Controller
{
public function getAll()
{
$data = Auteur::all();
return $data;
}
public function create(Request $request)
{
if (
isset($request->nom) and
isset($request->prenom) and
isset($request->email)
) {
$auteur = new Auteur();
$auteur->nom = $request->nom;
$auteur->prenom = $request->prenom;
$auteur->email = $request->email;
$auteur->save();
return $auteur;
}
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
public function update(Request $request)
{
$reponse = null;
$id = $request->id;
if (
isset($id) and isset($request->nom) and
isset($request->prenom) and
isset($request->email)
) {
$auteur = Auteur::find($id);
if ($auteur != null) {
$auteur->nom = $request->nom;
$auteur->prenom = $request->prenom;
$auteur->email = $request->email;
$auteur->save();
return $auteur;
} else {
$reponse["message"] = "auteur introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
}
public function delete($id)
{
if (isset($id)) {
$auteur = Auteur::find($id);
if ($auteur != null) {
$auteur->delete();
$reponse["message"] = "Supprimé avec succès.";
return $reponse;
} else {
$reponse["message"] = "auteur introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez préciser un identifiant SVP.";
return $reponse;
}
}
}
Contrôleur livre
php artisan make:controller LivreController
Dans le fichier créé, nous allons ajouter des méthodes pour afficher, insérer, modifier et supprimer un livre dans la base de données.
<?php
namespace App\Http\Controllers;
use App\Models\Livre;
use Illuminate\Http\Request;
class LivreController extends Controller
{
public function getAll()
{
$data = Livre::all();
return $data;
}
public function create(Request $request)
{
if (
isset($request->libelle) and
isset($request->nb_page) and
isset($request->categorie_id) and
isset($request->description) and
isset($request->image) and
isset($request->auteur_id)
) {
$livre = new Livre();
$livre->libelle = $request->libelle;
$livre->nb_page = $request->nb_page;
$livre->categorie_id = $request->categorie_id;
$livre->auteur_id = $request->auteur_id;
$livre->description = $request->description;
$livre->image = $request->image;
$livre->save();
return $livre;
}
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
public function update(Request $request)
{
$reponse = null;
$id = $request->id;
if (
isset($id) and
isset($request->libelle) and
isset($request->nb_page) and
isset($request->categorie_id) and
isset($request->description) and
isset($request->image) and
isset($request->auteur_id)
) {
$livre = Livre::find($id);
if ($livre != null) {
$livre->libelle = $request->libelle;
$livre->nb_page = $request->nb_page;
$livre->categorie_id = $request->categorie_id;
$livre->auteur_id = $request->auteur_id;
$livre->description = $request->description;
$livre->image = $request->image;
$livre->save();
return $livre;
} else {
$reponse["message"] = "Livre introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez renseigner tous les champs SVP.";
return $reponse;
}
}
public function delete($id)
{
if (isset($id)) {
$livre = Livre::find($id);
if ($livre != null) {
$livre->delete();
$reponse["message"] = "Supprimé avec succès.";
return $reponse;
} else {
$reponse["message"] = "Catégorie introuvable";
return $reponse;
}
} else {
$reponse["message"] = "Veuillez préciser un identifiant SVP.";
return $reponse;
}
}
}
Les routes
Les routes sont, comme le nom l’indique, des routes ou des moyens qui permettrons d’atteindre la logique implémentée dans les contrôleurs web. Elles permettons aussi de définir le format des URLs des APIs et aussi de préciser les méthode HTTP (Get, Post, etc.) que nos utilisateurs devront utiliser pour effectuer des actions dans notre base de données. Pour chaque module (categorie, auteur et livre) nous avons définir trois routes. Ainsi nous avons six routes au final. On définit les routes dans le fichier api.php (routes > api.php). Une routes est composée de trois parties.
Route::methode("/nom_de_api", [controler_ou_se_trouve_la_methode_a_executer, "methode_du_controler_a_executer"]);
//Exemple concret
Route::get("/categorie", [\App\Http\Controllers\CategorieController::class, "getAll"]);
Voici les routes dont nous avons besoin pour utiliser notre application.
Routes pour les catégories
//Categorie
Route::get("/categorie", [\App\Http\Controllers\CategorieController::class, "getAll"]);
Route::post("/categorie/create", [\App\Http\Controllers\CategorieController::class, "create"]);
Route::post("/categorie/update", [\App\Http\Controllers\CategorieController::class, "update"]);
Route::get("/categorie/delete/{id}", [\App\Http\Controllers\CategorieController::class, "delete"]);
Routes pour les auteurs
//Auteur
Route::get("/auteur", [\App\Http\Controllers\AuteurController::class, "getAll"]);
Route::post("/auteur/create", [\App\Http\Controllers\AuteurController::class, "create"]);
Route::post("/auteur/update", [\App\Http\Controllers\AuteurController::class, "update"]);
Route::get("/auteur/delete/{id}", [\App\Http\Controllers\AuteurController::class, "delete"]);
Routes pour les catégories
//Categorie
Route::get("/livre", [\App\Http\Controllers\LivreController::class, "getAll"]);
Route::post("/livre/create", [\App\Http\Controllers\LivreController::class, "create"]);
Route::post("/livre/update", [\App\Http\Controllers\LivreController::class, "update"]);
Route::get("/livre/delete/{id}", [\App\Http\Controllers\LivreController::class, "delete"]);
Une fois que les routes sont configurées, vous pourrez maintenant tester vos APIs avec un client HTTP (POSTMAN, par exemple). Voici un exemple du format de l’URL à saisir.
http://localhost:8000/api/[route]
//Exemple concret
http://localhost:8000/api/categorie/delete/3
Conclusion
Nous voici à la fin de notre petite aventure. Dans cet article, nous avons vu comment implémenter une API REST avec le framework Laravel. J’ai pris plaisir à écrire, cet article. J’espère donc que vous avez pris également plaisir à le lire. Je vous partage le projet que vous pourrez installer puis tester vous même. Vous pouvez aussi le télécharger depuis github. Allez à bientôt pour un prochain article, Peace ! 🥳