Il s'agit d'une version statique de l'intranet d'A. Jonquet, certaines fonctionnalités sont donc potentiellement non fonctionnelles.
Rejoindre la version dynamique 🔒
R401
Navigation

Introduction à API Platform

L'objectif de ce module est de vous familiariser avec le développement d'API web en utilisant API Platform.

Ce TP va servir à mettre en place le projet et à présenter les grandes lignes d'API Platform.

API Platform fait partie de ces nombreux « frameworks » comportant une grande part de « magie ». De nombreux points du sujet consistent soit à vous familiariser avec la documentation, le fonctionnement et la philosophie d'API Platform soit à exécuter une commande. Prenez le temps de lire la documentation et/ou de comprendre ce que vous faites, l'intérêt n'est pas ici de vous faire réaliser un tutoriel, mais de vous amener à comprendre ce qu'il se passe.

Remarque importante

Les notes des TP seront obtenues à partir de vos dépôts Git, vous devrez donc prendre grand soin de la qualité de ces dépôts et de leurs « commits ».

De manière similaire, les descriptions de vos « commits » devront être claires et informatives, afin de permettre l'évaluation de la progression de votre travail.

Objectifs de la séance

  • Gestion de versions à l'aide de Git
  • Gestion de projet à l'aide de Composer
  • Mise en place d'un service web à l'aide d'API Platform
  • Introduction à la configuration d'API Platform
  • Initialisation des données à l'aide de « fixtures »

Mise en place d'API Platform

Remarque importante

Le système de fichier du département informatique étant un peu poussif sur les accès aux fichiers. Et les projets Symfony sont constitués de nombreux fichiers. Vous êtes encouragé à travailler dans le répértoire « /working » de votre machine. Ce répertoire est un répertoire local à la machine, il n'utilise donc pas le système de fichier du département. En contrepartie, votre projet ne sera pas sauvegardé sur les serveurs du département et ne sera accessible que de cette machine. Vous penserez impérativement à sauvegarder votre travail sur le serveur GitLab au moins à chaque fin de séance.

Plusieurs solutions sont envisageables pour déployer une application API Platform. Nous retiendrons celle qui utilise l'outil symfony en ligne de commande (Symfony CLI).

Cette solution repose sur l'exécutable symfony et Composer. Vous commencerez par mettre à jour votre version de Composer, comme vous l'avez vu dans le TP de M. Cutrona. Si ce n'est pas déjà fait, installez ou mettez à jour l'exécutable symfony.

Vous pourrez ensuite créer un nouveau projet nommé r401-bookmarks-api :

symfony new r401-bookmarks-api --version 6.3

Cette commande va créer un squelette d'application Symfony dans un nouveau répertoire api-bookmark. Afin d'y ajouter Api Platform, dans le répertoire r401-bookmarks-api, vous installerez les composants PHP d'API Platform, sans inclure les fichiers de configuration de Docker :

composer require api api-platform/core:^3.2

Votre API est maintenant installée et fonctionnelle.

Travail réalisé dans cette partie
  • Installer un squelette d'application Symfony.
  • Y ajouter API Platform.

Gestion du dépôt Git

La gestion de versions et l'archivage seront réalisés à l'aide de Git. Lors de la création du projet, l'exécutable symfony a initialisé un dépôt et effectué un premier « commit ». Pour un rapide tour d'horizon de Git, vous pouvez vous référerez au site de Monsieur Nourrit.

Vous pourrez ensuite indiquer à Git de suivre tous les fichiers actuellement dans votre répertoire :

git add .

Vous réaliserez le second « commit » de votre dépôt :

git commit -m "require api dependencies"

Vous associerez votre dépôt local à un dépôt distant, nommé r401-bookmarks-api, sur le serveur GitLab du département. Vous penserez à ajouter votre intervenant de TP comme membre et à lui modifier ses droits comme « reporter ».

À partir de maintenant, vous réaliserez un « commit » après chaque question, avec un message clair et informatif, afin de permettre l'évaluation de la progression de votre travail.

Afin de gérer facilement la configuration de PhpStorm, le répertoire .idea de configuration du projet devra être ignoré dans votre dépôt.

Travail réalisé dans cette partie
  • Compléter le dépôt Git local pour le TP.
  • Répliquer le dépôt local sur le serveur distant GitLab.
  • Vérifier les utilisateurs et leurs droits.

Serveur de développement

L'application API Platform est installée dans votre répertoire de travail, dans le cadre du développement de l'application, une solution simple pour l'afficher dans un navigateur consiste à utiliser le serveur web local de symfony.

Le serveur doit exposer comme racine du serveur public le sous-répertoire public, la commande pour le démarrer est :

symfony serve

Si vous ouvrez l'URL http://127.0.0.1:8000, vous constaterez que vous obtenez l'accès à l'application Symfony sous-jacente. L'API est accessible sous la ressource /api de l'application Symfony. Pour l'instant votre API n'expose rien pour l'instant, puisque vous n'avez pas encore défini de données.

Afin de ne pas avoir à retenir la commande de lancement du serveur local, vous modifierez le fichier « composer.json » en ajoutant, dans la propriété scripts de l'objet de configuration, une nouvelle propriété start avec la commande comme valeur. Cette commande permettra de lancer le serveur de développement directement à l'aide de la commande suivante :

composer start

Afin d'éviter que la commande ne soit tuée au bout de 300 secondes, vous devez lever la restriction de durée d'exécution uniquement pour ce script.

Pour faciliter la prise en main de votre projet, décrivez la nouvelle commande Composer dans le fichier « composer.json ».

Notez que la liste des commandes peut être obtenue avec :

composer run --list

Les projets sont habituellement documentés pour permettre leur mis en route rapide. Ceci consiste à compléter un fichier Markdown « README.md » placé à la racine du projet.

Vous devez y faire figurer le nom de votre projet, votre nom en tant qu'auteur et donner les grandes lignes de l'installation, de la configuration et de la mise en route. Vous veillerez à garder ce fichier à jour tout au long du développement.

Travail réalisé dans cette partie
  • Lancement d'un serveur Web local.
  • Configuration d'une commande Composer.
  • Ajouter de la documentation du projet.

Style de codage

Votre API basée sur API Platform est un projet Symfony. Il convient donc de respecter le style de codage correspondant et PHP CS Fixer est l'outil officiel de Symfony et il est parfaitement intégré dans PhpStorm.

Vous devez en faire une dépendance de développement :

composer require --dev friendsofphp/php-cs-fixer

Vous configurerez votre éditeur pour qu'il utilise PHP CS Fixer pour formater votre code avec le fichier de configuration personnaliser fourni par Symfony : « .php-cs-fixer.dist.php »

Vous réaliserez ensuite un « commit » pour marquer cette évolution du projet.

Afin de faciliter et systématiser son utilisation, vous ajouterez des scripts Composer :

  • « test:cs » qui déclenche
    php-cs-fixer fix --dry-run
  • « fix:cs » qui déclenche
    php-cs-fixer fix
  • « test » qui déclenche le script « test:cs »
    @test:cs
Travail réalisé dans cette partie
  • Ajouter PHP CS Fixer comme dépendance du projet.
  • Configuration de votre éditeur de texte.
  • Configuration de commandes Composer.

Connexion de la base de données

L'API ne comporte pas encore de données et ne propose donc pas encore d'opérations.

Dans un premier temps, vous allez configurer l'accès à la base de données. Vous commencerez par créer une nouvelle base de données MySQL pour l'occasion, VOTRELOGIN_Bookmarks par exemple.

Ensuite, dans votre répertoire de travail, copiez le fichier « .env » dans le fichier « .env.local » puis modifiez la ligne correspondant à la connexion à la base de données :

Notez que la version du serveur est indispensable et peut être fixée dans l'URL ou dans le fichier « config/packages/doctrine.yaml ».

Travail réalisé dans cette partie
  • Connecter le projet à la base de donnée MySQL.
  • Définir la version du serveur de base de données.

Création d'une table pour les bookmarks

Afin d'avoir des données à exposer dans votre API, vous allez commencer par créer les tables permettant de stocker les données à afficher.

L'interaction avec la base de données se fera à l'aide des entités de Symfony. La gestion des entités sera réalisée à l'aide du générateur de Symfony. Vous installerez donc à l'aide de Composer le paquet PHP maker-bundle :

composer require --dev symfony/maker-bundle

Vous allez ensuite pouvoir créer l'entité représentant les données d'un bookmark :

bin/console make:entity

Vous l'appellerez Bookmark et en ferez une ressource API Platform. Vous ajouterez ensuite les propriétés suivantes :

  • name de type string de taille 255, ne pouvant pas être null,
  • description de type text, ne pouvant pas être null,
  • creationDate de type datetime, ne pouvant pas être null,
  • isPublic de type boolean, ne pouvant pas être null.
  • url de type text, ne pouvant pas être null.

Vous allez pouvoir préparer la migration de la base de données, en suivant la procédure suivante :

Dans un premier temps, vous vérifierez la validité des instructions SQL à l'aide de l'option --dump-sql de la sous-commande doctrine:schema:update :

bin/console doctrine:schema:update --complete --dump-sql

Le résultat ne doit comporter que la création d'un table Bookmark.

Si l'instruction SQL est valide, vous pouvez créer une migration de la base de données :

bin/console make:migration
Remarque importante

Un nouveau fichier apparait dans le répertoire « migrations » de votre projet, n'oubliez pas de l'ajouter à votre dépôt Git.

Appliquez ensuite cette nouvelle migration avec la sous-commande doctrine:migrations:migrate

bin/console doctrine:migrations:migrate

La table devrait maintenant être créée dans la base, vous pouvez le vérifier à l'aide de phpMyAdmin ou en essayant de réaliser une requête sur la table :

bin/console dbal:run-sql "SELECT * FROM bookmark"

Vous devriez obtenir ce résultat :

 [OK] The query yielded an empty result set.
Travail réalisé dans cette partie
  • Installation du paquet PHP maker-bundle.
  • Création de l'entité Bookmark.
  • Création de la table Bookmark dans la base de données.

Génération de données

Votre API expose maintenant des actions sur l'entité Bookmark, mais celle-ci ne comportant pas de données, les interactions sont relativement limitées.

Dans le cadre du développement, il est fréquent d'avoir recours aux « fixtures », pour initialiser automatiquement un jeu de données dans une table. L'automatisation de l'opération permet de la re-exécuter chaque fois que l'on souhaite remettre la base à neuf.

Vous allez donc installer l'outil de gestion des « fixtures » :

composer require orm-fixtures --dev

Vous pourrez ensuite générer un nouveau script de génération de contenu pour la table que vous appellerez BookmarkFixtures :

bin/console make:fixtures

Pour générer les données à insérer dans la base de données, de nombreuses solutions existent, nous allons utiliser un outil permettant de simplifier ce travail, Foundry :

composer require zenstruck/foundry --dev

Vous allez pouvoir ajouter une nouvelle forge de données pour l'entité Bookmark :

bin/console make:factory

Dans la méthode de classe getDefault, vous allez fournir des valeur par défaut pour chacun des attributs d'un bookmark. À l'exception de id qui est autogénéré.

En utilisant Faker, vous initialiserez les attributs comme suit :

Pour générer un jeu de données dans la base de données, vous n'avez plus qu'à simplement remplacer le contenu de la méthode load de BookmarkFixtures par le code suivant :

Vous pourriez ensuite, mais vous ne le ferez pas, remplir la base de données à l'aide de la commande suivante :

bin/console doctrine:fixtures:load --purge-with-truncate

Cette commande ne réinitialise pas les séquences des identifiants des tables et, si vous l'utilisez plusieurs fois de suite, les identifiants ne cesseront d'augmenter. Pour palier ce problème, et s'assurer d'avoir une base de données « toute neuve » à chaque fois, vous allez écrire un script Composer « db » qui recrée la base de données en enchaînant les commandes :

Vous documenterez évidemment ce nouveau script dans le fichier « README.md »

Encore une fois, vous pouvez vérifier que tout fonctionne correctement soit à l'aide de phpMyAdmin, soit en réalisant une requête :

bin/console dbal:run-sql "SELECT COUNT(*) FROM bookmark"

Vous devriez obtenir ce résultat :

 ---------- 
  COUNT(*)  
 ---------- 
  20        
 ---------- 
Travail réalisé dans cette partie
  • Installation des paquets PHP orm-fixtures et Foundry.
  • Création d'un script de génération d'entité Bookmark : BookmarkFactory.
  • Création d'un script de génération de données : BookmarkFixtures.
  • Génération de contenu automatiquement pour la table Bookmark.

Des données plus réalistes

Bien que fonctionnelle, cette solution n'est pas toujours satisfaisante, car les données générées ne sont forcément suffisamment réaliste, notamment lors du développement de l'application consommant l'API ou lors des tests.

Dans ce cas, on a généralement recours à un jeu de données construit à la main, avec lequel on remplit la base de données.

Le jeux de données étant relativement petit et afin de vous simplifier la lecture des données, vous allez utiliser des données au format JSON. Vous enregistrerez le fichier « bookmarks.json » (télécharger) dans un sous-répertoire data du répertoire DataFixtures. En utilisant file_get_contents et json_decode, vous chargerez le tableau contenant les données depuis le fichier, puis vous créerez un bookmark par ligne du tableau en lui fournissant les propriétés url, name et description de chaque élément du tableau.

Remarque importante

Vous devez faire référence au fichier bookmark.json depuis le fichier BookmarkFixtures.php. Vous ne pouvez pas utiliser le répertoire courant « . » qui fait référence au programme en cours d'exécution. Vous devez utiliser la constante magique qui donne le répertoire du fichier dans lequel elle est utilisée.

Après avoir chargé à nouveau vos « fixtures », vous pouvez vérifier le bon fonctionnement à l'aide de la requête suivante :

bin/console dbal:run-sql "SELECT COUNT(*) FROM bookmark"

Vous devriez obtenir ce résultat :

 ---------- 
  COUNT(*)  
 ---------- 
  67        
 ---------- 

Travail réalisé dans cette partie
  • Génération de contenu plus réaliste pour la table Bookmark.

Configuration des opérations API Platform

En vous rendant sur la page de votre API, vous constatez que par défaut, API Platform vous propose une représentation CRUD de vos entités, en utilisant le nom de l'entité comme nom de ressource.

Vous expérimenterez les différentes actions disponibles en créant de nouveaux bookmarks, en les modifiant, en en supprimant et en comparant le listage d'une collection ou d'un élément.

En testant un peu l'opération de listage des bookmarks, vous constaterez qu'ils sont triés selon leur id, ce qui n'a pas vraiment de sens. Vous remédierez à cela en ajoutant un attribut permettant de spécifier l'ordre par défaut, ici par ordre alphabétique des noms.

Vous ajouterez des options à votre collection sous la forme de tris et de filtres.

Ici, vous ajouterez trois types de filtres, mais vous pouvez librement explorer les filtres disponibles :

Travail réalisé dans cette partie
  • Ajout de tris et de filtres sur la collection.

Mise en place de tests

Vous avez dû remarquer que le test manuel des fonctionnalités est fastidieux. Afin d'améliorer la DX (expérience de développement) de votre projet, et surtout fiabiliser vos développements, vous allez mettre en place des tests automatisés. Il est possible d'effectuer des tests sur une application Symfony avec PHPUnit mais nous lui préférerons Codeception qui propose un module REST que nous avons adapté à API Platform.

Vous commencerez par installer la suite de tests de Codeception ainsi que les modules qui vous seront utiles :

composer require --dev --no-interaction \
                 codeception/codeception \
                 codeception/module-asserts \
                 codeception/module-symfony \
                 codeception/module-doctrine2 \
                 codeception/module-rest

Vous devez ensuite initialiser Codeception :

php vendor/bin/codecept bootstrap --namespace=App\\Tests --empty

Vous pourrez ensuite modifier l'environnement de tests en y ajoutant une base de données SQLite, dans le fichier « .env.test » à la racine de votre projet :

Vous configurerez Codeception pour qu'il utilise les fichiers « .env » et « .env.test » comme sources de paramètres dans « codeception.yml »

Votre première suite des tests s'appellera « Api » et sera générée par :

php vendor/bin/codecept generate:suite Api

Codeception génère du code PHP. Malheureusement, ce code n'est pas toujours valide au sens des règles fixées pour PHP CS Fixer. C'est pourquoi vous ajouterez une exclusion pour le répertoire tests/Support/_generated dans le fichier « .php-cs-fixer.dist.php »

Vous devez créer la base de données de test et y ajouter les tables. Cette démarche devant être facilement accessible lors du clonage du projet, vous allez définir un nouveau script Composer « test:codeception » qui contiendra les commandes suivantes :

Vous ajouterez un appel à ce script Composer dans le script « test », après l'appel au script « test:cs ».

Vous allez maintenant pouvoir ajouter des tests à votre projet, permettant d'automatiser vos interactions avec l'API pour tester les fonctionnalités que vous mettez en place. Les tests ne restent cependant que des garde-fous, ils ne remplacent pas un test réel lorsqu'une fonctionnalité est terminée.

Codeception propose un module REST rendant aisément accessibles les envois de données selon les diverses méthodes HTTP (POST, PUT, … mais sans ajouter l'en-tête Content-Type correspondant aux données JSON) et proposant un accès et des contrôles facilités sur les réponses HTTP dont les contenus sont JSON ou XML. Cependant, certains tests couramment utiles pour API Platform nécessitent une succession d'appels de méthodes du module REST. C'est pourquoi nous vous proposons un module développé en interne qui étend le module REST et qui permet de faciliter l'écriture des tests pour API Platform. Il précise en particulier les en-têtes Content-Type adéquats selon la méthode HTTP.

Placez le module « ApiPlatform » (télécharger) dans le répertoire tests/Support/Helper.

Pour résoudre des soucis d'accès à l'EntityManager au cours des tests entre le moteur de test et le navigateur de symfony, vous ajouterez un autre module développé en interne permettant de réinitialiser l'EntityManager entre chaque test.

Placez le module « EntityManagerReset » (télécharger) dans le répertoire tests/Support/Helper.

Vous activerez ensuite tous les modules nécessaires dans la suite Api en modifiant la propriété modules du fichier « Api.suite.yml » comme suit :

Vous placerez dans un répertoire tests/Api/Bookmark la classe de Cests suivante : « BookmarkGetCest.php » (télécharger)

Cette classe de Cests permet de tester l'accès à un signet. Lors de l'exécution de la commande suivante, le test devraient être valide avec toutes ses assertions :

composer test

Vous constaterez probablement des notifications de déprecation, qui bien qu'informatives, polluent l'affichage du résultat des tests. Pour les supprimer, vous pouvez ajouterez à votre projet une nouvelle dépendance Composer :

composer require --dev --no-interaction symfony/proxy-manager-bridge

Une fois l'environnement de test fonctionnel, vous ajouterez un nouveau jeu de tests pour la collection de signets et vous ferrez en sorte que les tests soient tous valides :« tests/Api/Bookmark/BookmarkGetCollectionCest.php » (télécharger).

Travail réalisé dans cette partie
  • Ajout des outils de test de Codeception.
  • Configuration de Codeception.
  • Mise en place de la base de données de test.
  • Ajout de tests sur les actions de la ressource Bookmark.
  • Validation de tous les tests sur la ressource Bookmark.
A. Jonquet DUT-INFO/REIMS