Dans l'introduction aux API, nous avons vu
que les API web utilisent le protocole HTTP pour permettre à des systèmes de communiquer
à travers le réseau.
Mais HTTP n'est qu'un moyen de transport. Il définit comment acheminer les données, pas du tout comment les organiser.
Pour structurer les échanges, les développeurs suivent des conventions.
La plus répandue s'appelle REST.
Le principe de REST
REST (Representational State Transfer) a été formalisé en 2000 par Roy Fielding, dans sa thèse de doctorat.
Le bonhomme n'est pas n'importe qui, il a coécrit les spécifications d'HTTP.
Son idée est simple, chaque chose dans ton système (un utilisateur, un produit, une commande)
est une ressource, identifiée par une URL unique.
Pour interagir avec ces ressources, on utilise les verbes HTTP :
- GET : lire une ressource. "Donne-moi les détails du produit n°42."
- POST : créer une nouvelle ressource. "Crée un nouveau compte utilisateur."
- PUT / PATCH : modifier une ressource existante. "Change l'adresse de livraison du client n°7."
- DELETE : supprimer une ressource. "Supprime l'article du panier."
C'est intuitif, l'URL dit sur quoi on agit et le verbe dit ce qu'on fait.
GET /produits → liste des produits
GET /produits/42 → détails du produit n°42
POST /produits → créer un nouveau produit
PUT /produits/42 → modifier le produit n°42
DELETE /produits/42 → supprimer le produit n°42
Les données sont échangées au format JSON, un format texte lisible par les humains
et par les machines. C'est le format que nous avons vu dans les exemples du chapitre précédent.
REST n'est pas un standard figé, c'est un style d'architecture, autrement dit un ensemble de bonnes pratiques.
Chaque développeur l'interprète à sa façon, ce qui explique que deux API "REST" peuvent être
très différentes l'une de l'autre.
Les deux règles qu'on oublie toujours
Derrière les verbes et les URL, REST pose deux principes qui paraissent abstraits mais qui ont des conséquences très concrètes au quotidien.
- Le serveur ne se souvient de rien : chaque appel doit contenir tout ce qu'il faut pour être traité, y compris l'identité de celui qui appelle. Le serveur ne garde pas de "conversation en cours" avec toi. C'est ce qui permet de mettre dix serveurs derrière la même adresse et d'envoyer chaque requête à n'importe lequel d'entre eux, donc d'encaisser la charge simplement en ajoutant des machines.
- Certains appels doivent pouvoir être rejoués : demander deux fois le produit n°42 doit donner le même résultat, et supprimer deux fois le produit n°42 doit laisser le système dans le même état. On dit que GET, PUT et DELETE sont idempotents. POST, lui, ne l'est pas, puisque deux appels créent deux ressources.
Cette deuxième règle explique un grand classique du e-commerce. Si le réseau coupe pendant la validation d'un panier, le téléphone du client va retenter l'appel automatiquement, et comme la création de commande passe par un POST, tu risques de facturer deux fois. C'est pour ça que les bonnes API de paiement demandent au client de générer lui-même un identifiant unique par tentative, afin de reconnaître le doublon et de renvoyer la commande déjà créée plutôt que d'en fabriquer une seconde.
Pourquoi REST a gagné
Avant REST, le standard dominant était SOAP, à l'origine l'acronyme de Simple Object Access Protocol.
Le "Simple" était d'ailleurs devenu tellement ironique que la version 1.2 de la norme, publiée en 2003,
a officiellement abandonné la signification de l'acronyme pour ne garder que les quatre lettres.
SOAP utilisait le format XML, beaucoup plus verbeux que JSON, et imposait une structure rigide
avec des enveloppes, des en-têtes et des schémas de validation.
Le même appel météo, dans les deux mondes.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header></soap:Header>
<soap:Body>
<m:GetMeteo xmlns:m="http://exemple.fr/meteo">
<m:Ville>Paris</m:Ville>
</m:GetMeteo>
</soap:Body>
</soap:Envelope>GET /meteo/paris
Et encore, j'ai simplifié la version SOAP. Dans la vraie vie, elle s'accompagne d'un fichier de description
(le WSDL) qui décrit chaque opération disponible, et souvent d'une couche de sécurité qui rajoute encore
plusieurs dizaines de lignes dans l'en-tête.
SOAP était conçu pour les grandes entreprises qui avaient besoin de garanties fortes
sur la structure des échanges, avec des transactions, de la signature de messages et une validation stricte.
Pour la majorité des cas d'usage du web, c'était comme utiliser un semi-remorque pour aller acheter le pain.
REST, avec sa simplicité et son utilisation naturelle d'HTTP, a rapidement séduit les développeurs.
Il n'y avait rien à installer, rien à générer, un navigateur suffisait à explorer l'API.
Aujourd'hui, l'immense majorité des API web sont REST ou s'en inspirent.
SOAP survit principalement dans les systèmes bancaires, les assurances, les transporteurs et les grandes
entreprises historiques. Si tu travailles avec ce genre de partenaires, tu en croiseras encore.
Les limites de REST
Malgré sa popularité, REST a quelques problèmes récurrents.
Le sur-chargement (over-fetching)
Quand tu demandes un produit, l'API te retourne tous ses champs : nom, description,
prix, avis, photos, caractéristiques techniques...
Même si tu n'avais besoin que du nom et du prix.
Sur un site mobile avec une connexion lente, recevoir des données inutiles gaspille
de la bande passante et ralentit l'affichage.
Le sous-chargement (under-fetching)
Inversement, si tu veux afficher un produit avec les avis de ses acheteurs et les produits similaires, il te faudra peut-être trois appels séparés.
GET /produits/42
GET /produits/42/avis
GET /produits/42/similaires
Trois allers-retours réseau au lieu d'un seul. Sur une fibre, personne ne le remarque. Sur un mobile en 4G dans le métro, chaque aller-retour coûte facilement une centaine de millisecondes, et ça s'additionne vite.
Le manque de spécification
Puisque REST est un style et pas un standard strict, deux API REST peuvent être très différentes.
L'une utilise /users, l'autre /utilisateurs. L'une met l'identifiant dans l'URL,
l'autre dans un paramètre de requête. L'une retourne les erreurs avec un
code 400, l'autre avec un code 422.
Pour chaque nouvelle API qu'on intègre, il faut lire la documentation et comprendre ses conventions.
C'est une des raisons pour lesquelles la qualité de la
documentation est si importante.
La question des actions métier
REST raisonne en ressources et en manipulation de données. Le problème, c'est que la vie réelle est pleine de verbes qui ne se rangent dans aucune case. Rembourser une commande, relancer un client, publier un article, annuler un abonnement, tout ça ne se traduit pas naturellement en "créer" ou "modifier".
Le réflexe est alors de tricher, en modifiant directement un champ de la ressource.
PATCH /abonnements/42 { "statut": "annule" }
POST /abonnements/42/annulation
La première version force le client à connaître la mécanique interne du système, et surtout elle ne dit rien de ce qu'il faut faire du remboursement ou de l'email de confirmation. La seconde nomme l'intention métier et laisse le serveur décider de tout le reste. Dans le doute, préfère toujours la seconde, c'est aussi ce que recommande le Domain Driven Design.
REST en pratique
Malgré ces limites, REST reste le choix par défaut pour la majorité des API web.
Sa simplicité est sa plus grande force, un développeur peut comprendre et utiliser une API REST
en quelques minutes, sans outillage particulier. Un simple navigateur ou un outil comme Postman suffit.
Il a aussi un avantage que l'on sous-estime souvent. Comme chaque ressource a une URL fixe et que les lectures
passent par des GET, tout l'écosystème HTTP fonctionne gratuitement par dessus, en particulier
le cache. Les navigateurs, les serveurs intermédiaires et les
CDN savent déjà mettre en cache une réponse REST sans qu'on ait rien à coder.
Les bonnes API REST suivent quelques conventions :
- Des noms de ressources au pluriel : /produits, /utilisateurs, /commandes.
- Des codes HTTP cohérents : 200 pour un succès, 201 pour une création, 404 pour une ressource introuvable, 500 pour une erreur serveur.
- Du versioning : /v1/produits, /v2/produits, pour faire évoluer l'API sans casser les clients existants.
- De la pagination : quand on a 10 000 produits, on ne les retourne pas tous d'un coup.
- Des erreurs exploitables : un message compréhensible et un code d'erreur stable, plutôt qu'un laconique "une erreur est survenue" que le client ne pourra jamais traiter automatiquement.
- Des limites d'usage annoncées : le nombre d'appels autorisés par minute, communiqué dans la réponse, pour que le client puisse se réguler au lieu de se faire couper brutalement.
Ces conventions ne sont pas obligatoires, mais les respecter rend l'API prévisible et agréable à utiliser.
C'est ce qui fait la différence entre une API qu'on intègre en une heure et une API qu'on maudit pendant des semaines.
Dans le chapitre suivant, nous verrons comment GraphQL s'attaque frontalement
aux deux premiers défauts de REST, le sur-chargement et le sous-chargement, et ce que ça coûte en échange.