API
Interfaces de programmation d'application ou Application Programming Interfaces.
Une API est une application.
Quand on parle dâapplication, on sous-entend souvent une application monolithique (un seul bloc). Depuis 15 ans, on sĂ©pare les modules pour que back et front puissent fonctionner sĂ©parĂ©ment. Notamment parce quâon est dans une Ăšre de micro-services.
Une API est une application sans front (ou peu) qui permet de rĂ©pondre Ă une question. Câest une interface qui rend un service. Elle retourne souvent du JSON.
Un micro-service est une API dans sa forme minimale (par exemple, un pour la base de donnĂ©es, un pour le front, etcâŠ).
On trouve de nombreuses API gratuites :
- api.gouv.fr : toutes les API du domaine public
JSON est utilisĂ© parce quâon fait de lâasynchrone et on affiche la rĂ©ponse seulement quand elle arrive.
Créer une API avec Symfony et API Platform
Projet Github : https://github.com/LSarribouette/mumbling-with-api-platform
Dans un terminal,
- se placer dans le bon dossier :
cd mon-repertoire
- créer un nouveau projet Symfony :
symfony new monApi
- se placer dans le projet :
cd monApi
- installer le paquet :
composer require api(alias pour API Platform)
- lancer le projet :
symfony server:startâ> lâAPI fonctionne sur le âlocalhost/apiâ (vide pour lâinstant)
Dans PhpStorm,
- ajouter une base de données de notre choix (ici, PostgreSQL avec Docker), en spécifiant
DATABASE_URLdans le .env.local
- créer la base de données :
symfony console doctrine:database:create
- créer une entité :
- installer le paquet :
composer require symfony/maker-bundle
- crĂ©er lâentitĂ© :
symfony console make:entity- choix du nom :
XMen
- choix si lâon veut la mettre en ressource de lâAPI (si oui, il crĂ©e tout pour nous) :
yes(ici, on dit oui uniquement si on veut mettre lâentitĂ© en public ; on dit non pour les utilisateur, par exemple)
- choix des propriĂ©tĂ©sâŠ
LâentitĂ© XMen est créée ainsi que son repository XMenRepository.
- choix du nom :
- installer le paquet :
- mettre à jour la structure de la base de données :
symfony console doctrine:schema:update --force
- ajouter éventuellement des données via un script SQL
Sur âlocalhost/apiâ, on voit maintenant lâentitĂ© avec :
- une documentation générée automatiquement
- les routes REST typiques (pour les collections et les items)
- les schĂ©mas de lâentitĂ© aux format .json et .jsonId

SĂ©curitĂ© : restreindre lâaccĂšs aux mĂ©thodes HTTP
Il est possible de restreindre lâaccĂšs Ă certaines mĂ©thodes HTTP comme DELETE, soit aux utilisateurs ayant un certain rĂŽle, soit complĂštement.
Lors de la crĂ©ation de lâentitĂ©, on a choisi de la mettre en ressource de lâAPI. Un attribut #[ApiResource] a Ă©tĂ© ajoutĂ© Ă la classe :
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\XMenRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: XMenRepository::class)]
#[ApiResource]
class XMen
{...}
On peut choisir de donner accÚs uniquement à la méthode GET en ajoutant un attribut #[Get] (ou plusieurs #[Get, Post]) en dessous du précédent :
#[ORM\Entity(repositoryClass: XMenRepository::class)]
#[ApiResource]
#[Get]
class XMen
{...}
De nombreux attributs sont disponibles : #[Get], #[GetCollection], #[Post], #[Put], #[Delete], #[Patch]âŠ
On peut Ă©galement choisir de donner accĂšs aux mĂ©thodes selon le rĂŽle de lâutilisateur en ajoutant un attribut #[IsGranted].
Interroger une API
Objectif : récupérer la liste des X-Men en JSON et remplir la liste dans la page HTML.
Dans un IDE (ici VSCode),
- créer une page HTML avec un titre, une liste, une balise
<script>pour JavaScript
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Interroger mon API</title>
</head>
<body>
<h1>Liste des X-Men</h1>
<ul id="maListe"></ul>
<script>
// a completer
</script>
</body>
</html>
Pour récupérer la liste des X-Men en JSON, trois options sont possibles :
- XML HTTP Request (non)
- AJAX avec jQuery (non)
- Fetch avec en paramĂštre lâURL de lâAPI que lâon veut joindre (oui)
Dans la balise <script>,
- récupérer la liste en JSON :
- méthode
fetch()avec en paramĂštre lâURL de la mĂ©thode souhaitĂ©e (ici, la GET pour la collection) finissant par .json
- un call back asynchrone avec
.thenpour transformer la chaĂźne de texte en JSON(une mĂ©thode anonyme oĂč on met dans la parenthĂšse avant la flĂšche le retour de la commande prĂ©cĂ©dente et aprĂšs la flĂšche on met la fonction Ă exĂ©cuter â si on met rien, ce sera un return)
- un autre
.thenpour afficher le résultat
- méthode
<script>
fetch('http://127.0.0.1:8000/api/x_mens.json')
.then((reponse) => reponse.json())
.then((json) => console.log(json));
</script>Lorsquâon lance le Live Server, la liste est visible dans lâinspecteur, onglet Console.
CORS_ALLOW_ORIGIN et on lui rajouter une condition *|local.
Pour remplir la liste dans la page HTML, on complĂšte le script JavaScript :
- faire une boucle sur le JSON oĂč Ă chaque objet trouvĂ©, on crĂ©e une
<li>- on rĂ©cupĂšre lâ
<ul>avec son id
- on boucle sur le tableau
- pour chaque ligne, on crée une
<li>
- on remplit le texte de la
<li>avec le pseudo
- on accroche la
<li>Ă la<ul>(quelque chose qui nâest raccrochĂ© Ă rien nâest pas visible)
- on rĂ©cupĂšre lâ
<script>
fetch('http://127.0.0.1:8000/api/x_mens.json')
.then((reponse) => reponse.json())
.then((json) => {
let monUl = document.getElementById("maListe");
for (const uneXMen of json) {
let monLi = document.createElement('li');
monLi.innerText = uneXMen.pseudo;
monUl.appendChild(monLi);
}
})
</script>
index() qui retourne le Twig index.html.twig,
> et ajouter le bout de code correspondant dans le {% block body %}.
Format Hydra
https://api-platform.com/docs/core/extending-jsonld-context/
Un Hydra est un autre format qui contient tout ce quâil y avait dans le fichier JSON, avec en plus dâautres informations comme le nombre dâĂ©lĂ©ments.
Si ce nombre est supĂ©rieur Ă 20, on a un URL qui permet dâavoir accĂšs aux 20 Ă©lĂ©ments suivants.
On peut également boucler sur un Hydra en utilisant member.
<script>
fetch('http://10.22.0.254:8002/api/superheroes')
.then((reponse) => reponse.json())
.then((json) => {
let monUl = document.getElementById("maListe");
for (const uneXMen of json["hydra:member"]) {
let monLi = document.createElement('li');
monLi.innerText = uneXMen.pseudo;
monUl.appendChild(monLi);
}
})
</script>
Authentification
Il est possible de limiter lâaccĂšs Ă une API Ă des utilisateurs ayant certains droits.
Pour cela, on utilise des JSON Web Token (JWT) grĂące au paquet LexikJWTAuthenticationBundle.
make:user (et non pas make:auth).