Les Developpeurs

API REST comprendre les principes fondamentaux pour enfin tout saisir

REST n'est pas une techno mais un style architectural défini par six contraintes précises. Découvrez pourquoi ignorer le sans-état ou mal utiliser les codes HTTP casse vos APIs, et comment l'éviter en production.

API REST comprendre les principes fondamentaux pour enfin tout saisir

Un collègue m'a envoyé un jour cette question par message : « J'ai une API qui renvoie du JSON, donc c'est du REST, non ? » J'ai mis dix minutes à lui répondre, parce que la vraie réponse est : pas forcément. Renvoyer du JSON ne dit rien de l'architecture. Une API REST, c'est un ensemble de contraintes bien précises — et si vous en violez une seule, vous n'avez plus tout à fait du REST. C'est exactement ce qui rend le sujet glissant au début.

Comprendre les principes fondamentaux d'une API REST, ce n'est pas apprendre une liste de verbes HTTP par cœur. C'est saisir pourquoi ces contraintes existent, et ce qui se casse dans votre système quand vous les ignorez. Je l'ai appris en production, à mes dépens.

Points clés à retenir

  • REST est un style architectural, pas une technologie ni un protocole.
  • Six contraintes le définissent ; la plus mal comprise est le sans état (stateless).
  • Les méthodes HTTP (GET, POST, PUT, PATCH, DELETE) se mappent sur les opérations CRUD, mais pas parfaitement.
  • Les codes de statut font partie du contrat : un 200 qui cache une erreur casse le client.
  • REST, RESTful et SOAP/GraphQL ne jouent pas dans la même catégorie.

Qu'est-ce qu'une API REST, au fond ?

Une API REST expose des ressources. Pas des actions, pas des fonctions. Des choses. Un utilisateur, une commande, une facture — chacune identifiée par une URI stable.

La confusion vient du mot « REST » lui-même. Representational State Transfer. Derrière ce nom un peu barbare, une idée simple : le client ne manipule jamais la ressource directement, il manipule une représentation de son état. Le plus souvent du JSON, parfois du XML, peu importe. Ce qui compte, c'est le va-et-vient : je lis un état, je le modifie, je renvoie une nouvelle représentation.

La différence entre ressource et collection

Un point que beaucoup d'équipes ratent au démarrage : distinguer une ressource unique de sa collection.

  • /users — la collection entière. Un GET ici renvoie une liste.
  • /users/42 — la ressource unique, ici l'utilisateur d'identifiant 42.
  • /users/42/orders — les sous-ressources rattachées à cet utilisateur.

Ce n'est pas de la coquetterie. Un URI bien construit rend l'API prévisible : un développeur qui découvre votre documentation peut deviner la moitié des endpoints sans qu'on les lui explique. J'ai repris une API où tout passait par /api?action=getUserById. Personne ne trouvait rien sans lire chaque ligne de la doc.

Les six contraintes qu'une API REST doit respecter

Voilà le cœur du sujet, et curieusement ce que la plupart des articles effleurent sans jamais le nommer. REST repose sur six contraintes architecturales. Elles ne sont pas décoratives : chacune répond à un problème concret.

Les six contraintes qu'une API REST doit respecter

1. Architecture client-serveur

Le client et le serveur évoluent séparément. Le serveur ne sait rien de l'interface qui l'appelle — site web, application mobile ou script interne. Cette séparation permet de faire évoluer l'un sans casser l'autre, tant que le contrat (l'URI, les formats, les statuts) reste stable.

2. Sans état (stateless)

C'est la contrainte la plus mal comprise, et celle qui fait le plus de dégâts quand on la néglige.

Chaque requête doit contenir toute l'information nécessaire pour être traitée. Le serveur ne conserve aucun contexte entre deux appels. Concrètement : si votre serveur garde une session en mémoire pour savoir qui vous êtes, vous n'êtes pas sans état.

Pourquoi c'est capital ? Parce qu'une requête sans état peut être traitée par n'importe quelle instance. Vous ajoutez une machine derrière le répartiteur de charge, et ça marche. Avec un état en mémoire, il faut coller chaque utilisateur à son serveur, ou synchroniser les sessions — et là, les ennuis commencent. J'ai vu une API tomber en panne un Black Friday simplement parce que les sessions étaient stockées sur une seule instance. On a perdu trois heures ce jour-là.

3. Cacheable

Si une réponse peut être mise en cache, elle doit l'indiquer. Un GET sur une ressource publique et peu changeante n'a aucune raison d'être recalculé à chaque appel. Les en-têtes HTTP (Cache-Control, ETag) servent exactement à ça. Le gain est souvent spectaculaire sur les ressources en lecture seule.

4. Système en couches

Le client n'a pas besoin de savoir s'il parle à votre serveur directement ou à un intermédiaire : proxy, passerelle, cache. Chaque couche ne voit que la suivante. C'est ce qui permet d'insérer un CDN ou un pare-feu sans que le client change une ligne.

5. Interface uniforme

Toutes les ressources s'exposent de la même manière : mêmes conventions d'URI, mêmes méthodes, mêmes conventions de réponse. C'est ce qui rend une API devinable. Sans cette uniformité, vous avez une collection d'endpoints, pas une API REST.

6. Code à la demande (facultatif)

Le serveur peut envoyer du code exécutable au client — du JavaScript, typiquement. Cette contrainte est optionnelle et rarement appliquée aujourd'hui. Je la mentionne par honnêteté, mais vous pouvez l'oublier dans 99 % des projets.

Comment les méthodes HTTP se mappent sur les opérations CRUD

Le mapping paraît évident sur le papier. Dans la pratique, une subtilité fait trébucher presque tout le monde : la différence entre PUT et PATCH.

Méthode Opération CRUD Sur quoi Remarque
GET Read Ressource ou collection Sans effet de bord — jamais
POST Create Collection Le serveur attribue souvent l'identifiant
PUT Update (complet) Ressource Remplace l'état entier
PATCH Update (partiel) Ressource Ne modifie que les champs fournis
DELETE Delete Ressource Idempotent

PUT ou PATCH : lequel choisir ?

PUT remplace. Si vous envoyez un PUT avec seulement deux champs sur cinq, les trois autres sont censés repartir à leur valeur par défaut. PATCH, lui, ne touche qu'à ce que vous lui donnez.

Méfiance, cependant : beaucoup d'API étiquetées « PATCH » se comportent en réalité comme des PUT. Ce n'est pas dramatique, mais c'est le genre d'incohérence qui finit par coûter des bugs en production. Choisissez une convention, et tenez-la partout.

Les codes de statut font partie du contrat

Un client REST ne lit pas seulement le corps de la réponse, il lit le statut. Renvoyer un 200 avec un champ {"error": "not found"} est une faute qui casse toute logique de retry automatique.

  • 200 — succès, avec contenu.
  • 201 — ressource créée ; l'URI de la nouvelle ressource va dans l'en-tête Location.
  • 204 — succès, sans contenu à renvoyer.
  • 400 — la requête est malformée.
  • 404 — la ressource n'existe pas.
  • 500 — le serveur a échoué. Et là, l'erreur est de votre côté.

Un détail qui m'a valu une soirée entière : la distinction entre 401 (non authentifié) et 403 (authentifié, mais pas autorisé). Les confondre envoie le client dans une boucle de re-authentification sans fin.

REST, RESTful, SOAP, GraphQL : comment s'y retrouver

Bon, avouons-le, le vocabulaire prête à confusion.

REST désigne le style architectural. RESTful qualifie une API qui respecte réellement ces contraintes — en pratique, beaucoup s'en approchent sans jamais y arriver complètement. C'est un idéal vers lequel on tend, pas un badge qu'on obtient.

SOAP est un protocole strict, avec un format de message imposé et un contrat WSDL. Plus lourd, très répandu dans les systèmes bancaires et les intégrations d'entreprise anciennes. GraphQL prend un angle opposé : un seul endpoint, et le client choisit précisément les champs qu'il veut, ce qui évite le sur-fetching et le sous-fetching.

Mon avis, que j'assume : pour une API publique ou une ressource CRUD classique, REST reste le meilleur choix. Il s'appuie sur HTTP, que tout le monde connaît, et le cache fonctionne nativement. GraphQL devient intéressant quand vos clients ont des besoins très hétérogènes — et douloureux quand vous devez gérer du cache ou limiter les requêtes abusives.

REST est-il obligatoirement en JSON ?

Non. REST est agnostique sur le format de représentation. JSON est le plus courant, XML reste utilisé dans certains secteurs, et on croise parfois du texte brut ou du binaire. Ce qui compte, c'est que le format soit annoncé via l'en-tête Content-Type.

Peut-on faire du REST sans HTTP ?

Sur le principe, oui — REST est un style architectural indépendant du protocole. Dans les faits, l'écrasante majorité des API REST s'appuient sur HTTP, parce qu'il fournit déjà les méthodes, les statuts et la gestion du cache.

Ce que personne ne dit sur REST

La partie que j'aurais aimé qu'on m'explique dès le début : REST n'est pas un objectif en soi. Personne ne vous décerne de médaille pour avoir respecté les six contraintes à la lettre.

Ce que ces contraintes achètent, en revanche, est très concret. Le sans état vous offre la scalabilité horizontale. L'interface uniforme vous donne une API que les autres développeurs devinent. Le cache réduit votre facture de serveurs. Chaque règle résout un problème réel — et quand vous en violez une, le problème revient, souvent des mois plus tard, sous la forme d'un incident en production à deux heures du matin.

Alors posez-vous une seule question avant votre prochaine API : si l'on ajoutait une seconde instance demain, tiendrait-elle la charge sans que je touche au code ? Si la réponse est non, cherchez l'état caché quelque part. Il est presque toujours là.

Franck Lefèvre

Franck Lefèvre est un expert reconnu en sécurité des réseaux, en cryptographie et en tests d'intrusion. Il accompagne depuis plusieurs années des organisations dans la protection de leurs infrastructures et la détection de vulnérabilités. Passionné par la transmission, il partage volontiers son savoir-faire avec rigueur et pédagogie.

Voir tous les articles →

Articles similaires