Dans les années 1990, le Web était régi par le HTTP et le TCP/IP. Mais au tournant du siècle, la complexité des réseaux était croissante, et les développeurs avaient besoin de les étendre en préservant la fiabilité, la performance et sans perdre en simplicité. Ils devaient imaginer leurs propres approches de haut niveau pour organiser le traitement et la distribution des informations par le biais d'applications web. Roy Fielding, doctorant à l’université d’Irvine en Californie, travaille sur la standardisation du protocole HTTP et trouve la solution.
Après avoir reçu les retours de plus de 500 développeurs, le jeune homme définit l’architecture REST en contraintes architecturales qui peuvent être résumées ainsi : « les composants doivent transmettre leur état interne dans un format standard, indépendant de l’implémentation ». « Le nom Representational State Transfer (Transfert d’état représentationnel) a été choisi pour évoquer l’image de comment une application Web bien conçue doit fonctionner : un réseau de pages (une machine-état virtuelle) où l’utilisateur avance à travers l’application en choisissant des liens (transitions d’état), ce qui entraîne le transfert de la prochaine page (le prochain état de l’application) étant transférée vers l’utilisateur, et généré pour son utilisation », explique Roy Fielding.
Le REST a été originellement conçu pour un service qui héberge des ressources (de l’HTML et des hyperliens à l’époque) à différentes URL et URI. Cela respecte les principes d’une bon design de logiciel : interfaces uniformes, composants sans états, utilisation de cache et des services qui peuvent être joints ou superposés.
Le REST en pratique
Ces temps-ci, ce paradigme n’est plus utilisé de la même manière qu’il l’était au temps de cette citation. Les développeurs utilisent plutôt une API HTTP et du JSON pour fournir les données aux applications. On parle d’application RESTful. Dans ce style, un client Web demande une ressource en utilisant une URL formatée de manière conventionnée. En retour, il reçoit un JSON d’une forme que l’on s’impose, qui décrit la ressource avec des paires clé-valeur. Si l’on prend par exemple une API autour de la musique, il y aurait une URL d’arrivée qui ressemblerait à servicemusique/albums/1234, où 1234 serait l’ID d’une ressource. La réponse JSON à une requête HTTP GET serait alors :
Listing 1. Un exemple de JSON de l’application ServiceMusique
L’endpoint répond avec des données qui décrivent cette ressource. Elles doivent respecter l’obligation du service de ne rien révéler de son implémentation. Les requêtes GET doivent être idempotent (ne doivent rien changer). Souvent, lancer une requête sur un dossier comme servicemusique/albums renvoie une liste d’albums. Les autres requêtes HTTP DELETE, PUT et POST respectivement suppriment cette ressource, la modifient ou en créent une nouvelle. POST prend comme argument un JSON semblable au Listing 1; pareil pour PUT qui donne en plus en argument l’ID de la ressource à modifier (ici, HTTP PUT servicemusique/albums/1234). L’endpoint accepte des filtres et des paramètres de recherches, comme celui-ci :
Quand une API devient plus complexe, la représentation des ressources devient forcément moins cohérente. Supposons que notre API ServiceMusique tague les albums en fonction de leur style ou de leur genre musical. Il est alors possible d’associer tag à album ou album à tag. L’approche d’une API dite RESTful se décide à ses préférences. La règle qui est la plus importante, c’est de définir une logique et de la respecter. Il faut que la syntaxe URL soit suffisamment cohérente pour qu’il soit facile à quelqu’un d’écrire le code désiré avec cette API.
Ces temps-ci, les clients sont écrits en JavaScript avec l’un des nombreux frameworks à disposition. Des requêtes de type Ajax sont souvent utilisées pour s’occuper des détails dans les applications d’une seule page. Les services (y compris les microservices) utilisent des API RESTful car elles sont utilisables dans un grand nombre de piles technologiques qui ont adopté ces conventions.
REST vs SOAP
Là où le REST est une architecture qui se comprend d’elle-même, d’autres styles de relations client-service n’ont pas cette souplesse, comme le modèle Remote Procedure Call (Appel de procédure à distance, RPC). Ce modèle prévoit exactement les conditions des interactions entre serveur et client, puis ils communiquent via des appels de fonctions dans le code local. Le RPC transforme les appels normaux en appels réseaux. Sa rigueur peut être bénéfique dans certaines situation, mais la rigidité de RPC oblige à ce que si le serveur ou le client fait un changement, alors l’autre doit faire également un changement, et les conditions d’interaction doivent être redéfinies.
L’un des exemples de RPC les plus connus est le Simple Object Access Protocol (Protocole d’accès aux objets simples, SOAP). C’était l’un des piliers de l’architecture orientée service (SOA) des années 2000. Ce protocole utilise des définitions en XML pour définir les interactions client-service. Les services exposent leurs spécifications, puis les clients les analysent pour découvrir leurs capacités. Le SOAP n’a pas survécu au temps, notamment à cause du facteur de complexité qu’ajoute cette manière de définir les interactions. La SOA et le SOAP créent une surcharge de travail, alors que celui des développeurs est déjà complexe.
Là où le système de RPC et SOA ont un contrat formel entre le client et le serveur, le REST et les applications RESTful n’en ont pas. Mais à l’inverse, là où le REST veut que le client n’ait que très peu d’informations sur le service en amont, les clients RESTful, eux, en sont informés. Un véritable client REST serait plus sophistiqué dans ses normes afin de l'être moins dans ses spécificités. Les applications RESTful sont donc un entre-deux : pas de contrat, mais quand même renseigné.
En théorie, le REST sépare le client du serveur, mais dans la réalité, le RESTful les rassemblent. (Crédit photo : IDG)
Les services RESTful (du type JSON-URL) maximisent la vitesse de développement. Ce n’est donc pas une surprise que ce modèle soit l’un des plus populaires dans le monde. Mais l’approche RESTful a tout de même des inconvénients, comme sa tendance à tendre vers la complexité. On le voit de plus en plus avec la progression des clients Web modernes qui doivent recevoir du JSON et le transforment dynamiquement en interfaces utilisateur.
L’oubli du HATEOAS
En cause, la plupart des développeurs qui mettent en œuvre le REST ont abandonné l'un de ses piliers d'origine. Le principe Hypermédia as the Engine of Application State (Hypermédia comme moteur de l'état de l'application, HATEOAS). En substance, cela signifie qu’il ne faudrait émettre que des hypermédias (HTML, XML, etc.) à partir de services - une idée qui est directement opposée à l'émission de JSON comme moyen de distribution. Fielding appelle ce principe la contrainte hypermédia, et il n'a pas manqué de souligner son non-respect généralisé :
« Une API REST ne devrait pas définir de noms de ressources fixes ou des hiérarchies (créant un couple client et serveur). Les serveurs doivent pouvoir être libre de contrôler leurs propres nomenclatures. À la place, il faut permettre aux serveurs d’informer les clients sur la manière de construire des URI au bon format, comme dans les formulaires HTML et les modèles d’URI, en définissant ces instructions dans les types de médias et les relations de lien ».
La plupart des API RESTful passent outre cet aspect essentiel du style REST. Les clients sont censé simplement récupérer le résultat du service – ce qui inclut toutes les données nécessaires pour interagir avec le service. La fonction première de l’hypermédia est de contenir à la fois la description des ressources et comment les naviguer. Carson Gross, inventeur de l’HTMX, s’est récemment demandé pourquoi dans son blog.
Les critiques du style RESTful comparé au design voulu par Roy Fielding sont réelles. Maintenir des services en HTTP et JSON est difficile. Mais l’utilisation réelle d’aujourd’hui reste les réponses JSON et les structures URL type RPC. Ce style a au moins l’avantage d’une utilisation courante, d’une implémentation large et d’une sémantique facile à comprendre.
Tous les développeurs Web en poste aujourd’hui ont l’obligation de connaître les principes du REST et comment ils sont appliqués dans les applications RESTful d’aujourd’hui.
Commentaire