Créer une API REST avec Laravel 5.5
L’objectif de cette suite de tutoriels sur Laravel 5.5 est de permettre au développeur web de déployer une API REST de qualité sur le Net.
La troisième étape consiste à écrire le code PHP nécessaire afin de créer des services de l’API REST. Ces services pourront être consommés par une application web, une application mobile ou même un autre service.
Récits utilisateur proposés
- En tant que développeur, j’aimerais une ressource API REST qui retourne la liste des mesures.
- Route : GET /api/measures/
- En tant que développeur, j’aimerais enregistrer une mesure de ma station de qualité de l’air afin de conserver l’historique des mesures.
- Une mesure est composée des attributs suivants :
- id, value, description, date de création, date de modification.
- Route : POST /api/measures/
- Une mesure est composée des attributs suivants :
Plan de match pour ce tutoriel
- Se familiariser avec la structure du cadriciel Laravel.
- Configurer la base de données (voir le fichier .env).
- Créer et lancer une migration afin de modifier la base de données.
- Créer un modèle basé sur le patron de conception Active Record.
- Créer un contrôleur avec des actions (méthodes) qui permettront la gestion de la ressource.
- Créer des routes ou chemins vers les ressources.
- Configurer les ressources (DTO).
- Écrire et exécuter les tests.
C’est donc un tutoriel très chargé. N’oubliez pas qu’il me fera plaisir de répondre à vos questions en bas de page. Bon succès!
Créer une migration de base de données
Note : La base de données MySQL doit avoir été configurée dans le tutoriel précédent.
Une migration correspond à une modification à la base de données. La première migration consiste à créer une nouvelle table dans la BD.
$ php artisan make:migration create_measures_table –create=measures
# Created Migration: 2018_01_25_143838_measure
Une fois le fichier généré, ouvrez-le et explorez cette migration dans le dossier databases/migrations.
Méthodes up et down de la migration
Compléter les méthodes up et down. Basez-vous sur l’exemple déjà présent dans le dossier databases/migrations. Vous devrez définir les attributs de la nouvelle table.
- id increments
- value double
- description string
- timestamps
Types des champs
- increments : permet de définir un champ auto-increment avec clé primaire.
- double : permet de définir un nombre à virgule flottante.
- string : permet de définir un champ de type chaîne de caractères.
- timestamps : génère deux champs qui entreposent les dates de création et de modification d’un enregistrement.
Plusieurs autres types sont disponibles dans la documentation officielle.
Appliquer la migration
Avec la commande suivante, la base de données sera détruite et reconstruite avec les migrations à appliquer.
$ php artisan migrate:fresh
# Dropped all tables successfully.
# Migration table created successfully.
# Migrating: 2018_01_25_143838_measure
# Migrated: 2018_01_25_143838_measure
Visualiser la structure de la base de données avec MySQL Workbench
Afin de mieux visualiser la structure de la base de données, il est possible d’utiliser un explorateur de base de données (ex: SQLYog Community ou MySQL Workbench ).
La configuration de connexion devrait ressembler à ceci :
- Hôte : api.app ou 192.168.10.10
- Utilisateur : homestead
- Mot de passe : secret
- Port : 33030 ou 3306
Créer un nouveau modèle
Afin d’établir le contact entre notre application et la base de données, il est proposé de créer un nouveau modèle. Ce modèle respecte le patron de conception Active Record.
$ php artisan make:model Measure
# Model created successfully.
# voir la racine du dossier app
Créer un contrôleur associé
Le contrôleur recevra les requêtes de vos clients. Il utilisera le modèle préalablement créé afin d’interagir avec la base de données.
$ php artisan make:controller MeasureController –resource –model=Measure
ou
$ php artisan make:controller MeasureController -r -m Measure
# Controller created successfully.
# voir le dossier app/Http/Controllers
Afficher les routes de l’application
Le système de routage a pour fonction de diriger une requête HTTP vers la bonne action du bon contrôleur. Pour l’instant, seules les routes par défaut sont présentes. Il faudra donc configurer de nouvelles routes afin de rendre les actions disponibles de notre nouveau contrôleur.
$ php artisan route:list
# Notez les routes disponibles
Ajout de routes pour le contrôleur
Créer le fichier /routes/api.php et y enregistrer une ressource
Route::resource(‘measures’, ‘MeasureController’);
Afficher les routes avec :
$ php artisan route:list
Notez que les routes pour measures sont disponibles.
Implémentation de l’action index de MeasureController
Ajouter le code suivant dans le corps de la méthode index() :
return [‘kiwi’, ‘banane’, ‘orange’];
Tester l’action index
Lancer une requête GET vers la route index. Vous pouvez le faire avec votre navigateur, Postman ou cUrl.
$ curl http://api.app/api/measures
$ chrome http://api.app/api/measures
Utiliser le modèle dans l’action index de MeasureController
use App\Measure
public function index()
{
$measure = new Measure();
$measure->value = 10;
$measure->description = ‘Co2’;
$measure->save();
return Measure::all();
}
Lancer une requête GET vers la route index afin de tester l’action :
$ curl http://api.app/api/measures
Faire un survol de l’article suivant :
Créer une ressource
En créant une ressource, nous pourrons spécifier les attributs à retourner au client. Cette pratique vise à garder le contrôle sur les données qui seront retournées au client.
Prenons par exemple le modèle fictif User. Un utilisateur possède un mot de passe. Par contre, nous ne voulons pas que le hash du mot de passe soit retourné au client. Il serait donc facile de configurer cette règle dans la ressource. Ce patron de conception se nomme DTO (Data Transfert Object).
$ php artisan make:resource MeasureResource
# Resource created successfully.
# voir app\Http\Resources et modifier le fichier généré
public function toArray($request)
{
return [
‘id’ => $this->id,
‘value’ => $this->value,
‘description’ => $this->description,
];
}
Afficher les measures :
- chrome http://api.app/api/measures
JSON Formatter
Installer JSON Formatter afin de faciliter la lecture des réponses JSON.
Modifier l’action index du contrôleur afin d’utiliser la nouvelle ressource
Voici le code modifié afin d’utiliser la nouvelle ressource créée. Afin d’utiliser cette classe, vous devrez ajouter l’instruction use en haut du fichier.
public function index()
{
$measure = new Measure();
$measure->value = 10;
$measure->description = ‘Co2’;
$measure->save();
return new MeasureResource(Measure::find(1));
}
- chrome http://api.app/api/measures
Collection de ressources
Afin de retourner une collection, la méthode statique collection de la ressource est offerte.
…
return MeasureResource::collection(Measure::all());
..
…
return MeasureResource::collection(Measure::paginate(3));
…
Faire un Git push sur Gitlab.
Défi
Comme défi, programmer les actions suivantes :
- index, /api/measures/ GET
- store, /api/measures/ POST
- show, /api/measures/1 GET
- update, /api/measures/1 PUT
- destroy /api/measures/1 DELETE
- index : retourne tous les enregistrements
- store : sauvegarde un enregistrement
- show : affiche un enregistrement
- update : met à jour un enregistrement
- destroy : supprime un enregistrement
Ajouter des données de tests dans la BD – Seeding
Lecture : https://laravel.com/docs/5.5/seeding
$ php artisan make:seeder MeasureTableSeeder
# Voir le dossier /database/seeds
Adapter le code suivant et créer 5 enregistrements
DB::table(‘users’)->insert([
‘name’ => ‘admin’,
’email’ => ‘admin@yopmail.com’,
‘password’ => bcrypt(‘secret’),
]);
Lancer la migration avec seed
$ php artisan migrate:refresh –seed
Créer une classe Test pour la ressource
$ php artisan make:test MeasureTest
Lancer les tests
$ vendor/phpunit/phpunit/phpunit
Mettre en place les tests automatisés
Ajouter un test afin de vérifier la méthode POST :
public function testPostMeasureTest()
{
$response = $this->post(‘/api/measures’,
[‘value’=> ‘3’, ‘description’=>’co2’],
[‘Accept’=> ‘application/json’]);
$response->assertJsonFragment([‘value’=>’3’]);
$response->assertStatus(200);
}
Note : L’action pourrait aussi retourner un code 201. Peut-être devrez-vous modifier votre test.
Ajouter un test afin de vérifier la méthode POST lorsque le JSON est incomplet :
public function testPostMeasureWithoutValueTest()
{
$response = $this->post(‘/api/measures’,
[‘description’=>’co2’],
[‘Accept’=> ‘application/json’]);
$response->assertJsonFragment(
[« value »=>[« The value field is required. »]]);
$response->assertStatus(422);
}
Lancer les tests
$ vendor/phpunit/phpunit/phpunit
Note : Si le dernier test ajouté est en échec, c’est normal. Le prochain tutoriel vous permettra d’ajouter de la robustesse à votre action et retourner les messages d’erreur appropriés.
Pousser sur Gitlab
Faire un Git push sur Gitlab.
Bravo!
Bravo, votre environnement de développement avec Homestead, Vagrant, PHP, MySQL est fonctionnel.
Configurons une application qui utilise le cadriciel Laravel.
Références et lectures
- https://www.getpostman.com/
- https://github.com/symfony/symfony/
- https://vagrantup.com/downloads.html
Robustesse de votre code
Maintenant que votre API REST est fonctionnelle, il faut améliorer la robustesse afin de garantir le format des données en entrée et retourner les messages d’erreur pertinents à votre client.
Facebook Comments