Votre API n'a pas toujours besoin d'être un produit
Les API HTTP/JSON sont omniprésentes dans nos applications web. Certes, le web implique de faire communiquer le navigateur d'un utilisateur avec le serveur qui gère les données, mais ça ne veut pas dire qu'il faut traiter toutes les API comme un produit à part entière. Nos API mériteraient parfois d'être un peu plus discrètes dans l'architecture d'une application web.
Contents
- Histoire abrégée du web
- Les API, leurs avantages et leurs contraintes
- Vous n’en avez pas besoin
- Conclusion
Histoire abrégée du web
Au commencement, des documents
Les premières pages web ne ressemblaient pas du tout à ce qu’on connaît aujourd’hui. Prenez par exemple cette page web datant du début des années 90 : quelques documents sans images, sans styles, reliés par des liens hypertextes (je vous laisse juger de la lisibilité par rapport à un site moderne). Le web était avant tout un réseau permettant d’accéder à de l’information sous forme de documents organisés en réseau (web).
Le protocole HTTP date de cette époque, il est parfaitement optimisé pour cet usage de transport de documents hypermédia (d’où le HT au début de HTTP), avec un peu d’interaction basée sur les formulaires.
jQuery, XHR et le rejet de la navigation
L’usage du web a explosé. Les sites web se sont faits plus nombreux, plus riches en contenu, et surtout plus interactifs. Les documents se sont faits de moins en moins statiques pour une personnalisation accrue de l’expérience des internautes.
En conséquence, le web a ralenti (il fallait générer les pages dynamiquement, et le réseau n’était pas encore aussi rapide qu’aujourd’hui dans tous les foyers) et certains sites ont commencé à ressembler à des applications plutôt qu’à des documents reliés entre eux.
C’est pour cette raison qu’on a commencé à user et abuser des requêtes XHR pour rendre nos sites web plus interactifs1. Recharger une page entière pour n’en changer qu’un petit bout ne constitue pas une expérience utilisateur satisfaisante si le temps de chargement est trop important.
Le navigateur a pris une direction : plutôt que d’augmenter les possibilités du langage HTML et du protocole HTTP, le langage JavaScript a permis de coder dans le navigateur des interactions spécifiques pour chaque site web. On a pu changer des parties de la page en faisant des requêtes HTTP directement en JS plutôt qu’avec les moyens (limités) de HTML que sont les liens et formulaires.
Single Page Application, aka le navigateur dans le navigateur
L’industrie du développement web s’est engouffrée dans cette voie pour devenir ce qu’on connaît aujourd’hui. Le contenu du viewport de votre navigateur est entièrement géré par du code JS. Les requêtes HTTP sont envoyées par du JS, les réponses traitées par du JS. L’historique, le cache, le routage, la gestion du scrolling sont gérés en JavaScript. Bref, il y a un navigateur dans votre navigateur.
Pour faire tout ça, les applications JS sont devenues des clients lourds, spécifiques à chaque application. Elles récupèrent les données auprès d’API qui, n’ayant plus que des données à transmettre, sont devenues des API HTTP/JSON comme on les connaît si bien aujourd’hui.
Les API, leurs avantages et leurs contraintes
Cette architecture avec un frontend spécifique et une API qui gère uniquement des données a créé plusieurs opportunités :
- Possibilité de confier le frontend et le backend à des équipes différentes
- Possibilité de coder plusieurs frontends différents pour la même API
- Possibilité de développer un frontend en interne en utilisant l’API qui est par ailleurs un produit à part entière de votre entreprise
C’est bien le principal avantage d’une API de données. Elle permet de répondre à des besoins variés d’utilisateurs variés. Néanmoins, on ne profite de ces avantages qu’à condition d’adopter toutes les bonnes pratiques de gestion d’un produit :
- rétrocompatibilité
- documentation
- priorisation et arbitrage des fonctionnalités demandées par de multiples utilisateurs
- etc.
Vous n’en avez pas besoin
L’ennui avec l’industrie du web aujourd’hui, c’est qu’on adopte cette architecture un peu trop facilement, sans se poser la question « Ai-je besoin de ces bénéfices ? Est-ce que le coût engendré n’est pas trop élevé ? »
Il y a pourtant beaucoup de situations où l’on pourrait simplifier la donne. Si votre backend n’a qu’un consommateur et que ce consommateur est sous votre contrôle (ce qui est le cas quand une équipe développe un produit full-stack), alors vous pouvez vous passer de rétrocompatibilité lors des changements. Vous pouvez vous passer d’une documentation utilisateur pour votre API au profit d’une documentation globale de l’application. Vous pouvez même vous passer du format JSON au profit, par exemple, de formats binaires comme Protobuf.
Revenez aux documents (sans sacrifier en interactivité)
L’architecture Single-Page-Application nous encourage à développer une API JSON. Tous les frameworks modernes sont suréquipés pour utiliser une API de données JSON. Pourtant, il est parfaitement possible de développer une application basée sur l’échange de documents HTML. Beaucoup d’applications sont encore développées en Ruby on Rails, par exemple, exploitant les formulaires, les liens et la construction de HTML côté serveur.
La tendance Single-Page Application est devenue populaire, entre autres raisons, par la possibilité de s’affranchir d’un rechargement complet de la page à chaque navigation ou soumission de formulaires. La bibliothèque HTMX génère beaucoup de discussions récemment parce qu’elle permet justement d’éviter ce rechargement complet de document tout en gardant une approche basée sur les documents pour les échanges navigateur/serveur et donc en évitant d’imposer à notre backend une rétrocompatibilité et à notre frontend une quantité astronomique de JavaScript.
Cette approche est parfaitement adaptée à beaucoup d’applications modernes où la logique métier côté client peut être limitée (applications de gestion avec des tonnes de formulaires, dashboards, etc.)2.
L’API comme détail d’implémentation
Même en restant dans l’écosystème JavaScript, il est aujourd’hui possible de s’affranchir d’une API HTTP/JSON (au sens d’une API séparée avec les contraintes évoquées plus haut). Le principe des loaders en React Router/Remix, la primitive $server
avec Qwik, les React Server Components sont autant de choses qui rapprochent le client et le serveur au point que l’API JSON entre les deux n’est plus qu’un détail d’implémentation pour les faire communiquer 3.
Si vous n’utilisez pas ces frameworks, cacher l’API HTTP se traduit souvent par de la génération de code. Les méthodes côté serveur (Controllers) deviennent des méthodes JS à utiliser dans votre appli frontend après un processus automatisé de génération de code (basé, par exemple, sur OpenAPI ou Protobuf). Si vous changez une méthode côté serveur, vous pouvez utiliser la nouvelle version côté client sans penser « Requête HTTP ».
Dans tous ces cas, il y a bien une API HTTP entre le navigateur du client et le serveur, mais vous ne l’avez pas codée, et vous ne l’appelez pas explicitement. On perd les avantages mentionnés plus haut (il n’est plus possible facilement d’appeler cette API depuis une autre application par exemple), mais on s’affranchit aussi des contraintes associées à une API de type « produit ».
Le pattern Back For Front
Il y a des situations où le backend de votre application est en dehors de votre contrôle. Peut-être qu’il est géré par une autre équipe, peut-être que c’est un produit tiers, peut-être qu’il est mis à disposition en tant que produit à d’autres consommateurs. Dans ce cas, les contraintes de rétrocompatibilité, de documentation, etc., existent de facto.
Dans ces circonstances, il peut être utile d’introduire un autre composant serveur entre votre application frontend et cette API. Ce composant sera dédié à votre application (donc il pourra évoluer avec sans contraintes) et lui fera bénéficier des avantages du serveur (gestion de cache mutualisé, validation côté serveur, authentification, performance de certains traitements algorithmiques, etc.).
Ce pattern est connu sous le nom de Back For Front et est encore sous-utilisé selon moi.
Conclusion
Pour votre prochaine application web, ralentissez un peu avant de dégainer l’arme « API REST / JSON ».
- Posez-vous les bonnes questions : Qui dépend de mon backend ? Combien d’applications ? Qui les contrôle ?
- Envisagez d’abandonner complètement l’architecture client/serveur au profit de documents, éventuellement avec HTMX2.
- Traitez votre API comme un détail d’implémentation, une manière de traverser le réseau (l’approche choisie par React, Next, Remix, Qwik, mais que vous pouvez choisir vous-même).
- Si votre API est en dehors de votre contrôle ou consommée par d’autres clients, introduisez un Back For Front pour que votre application bénéficie des avantages d’un serveur sous votre contrôle.
Toute cette approche a néanmoins un prérequis : arrêter de séparer les développeurs frontend des développeurs backend. S’ils développent le même produit, ils doivent travailler ensemble.
-
XHR est arrivé dans les navigateurs à partir de 1999. ↩
-
Pour en savoir plus, je vous renvoie vers ma conférence à ce sujet au BreizhCamp en 2024. ↩ ↩2
-
Ce point est développé dans la conférence de Ryan Florence “Mind the gap” (en anglais). ↩