Faire du REST social avec HATEOAS
Fabian Piau | mercredi 2 juillet 2014 - 19:06L’article « API, REST, JSON, XML, HTTP, URI… Vous parlez quelle langue en fait? » exposait quelques principes sur les webservices et les technologies associées, en particulier REST. Maintenant que vous êtes incollable sur le sujet, continuons un peu et introduisons HATEOAS. Bien que le nom soit un peu barbare, il n’y a aucun rapport avec un quelconque personnage du seigneur des anneaux!
Reprenons l’exemple du trajet en train du premier article. Notez que tous les exemples qui suivent sont en JSON, mais l’utilisation du XML est tout à fait possible.
{ "trainNum": 123456789, "departure": {"station": "Bruxelles-Central", "time": "07:28"}, "arrival": {"station": "Liège-Guillemins", "time": "08:25"} }
Ce message décrit un trajet en train en donnant diverses informations telles que le numéro du train, les gares de départ et d’arrivée et les horaires. Par contre, il n’y a aucune information liée au contexte. En se basant uniquement sur le contenu de ce message, on ne peut pas deviner sa provenance ou le moyen pour obtenir davantage d’informations (sur le trajet, le train, etc.). C’est le moment où notre cher compagnon HATEOAS intervient.
HATEOAS est l’acronyme de Hypermedia as the Engine of Application State. Tout de suite, c’est plus clair! Non? Ok, moi non plus. Concrètement, c’est un moyen d’ajouter des informations contextuelles à un message. On parle de la « contrainte » HATEOAS sur REST car le but est que ces données ajoutées respectent un format bien défini et universel. Ce standard (comme tous les autres) est indispensable afin d’éviter que chacun crée son propre format maison et que cela devienne spécifique par API. On perdrait alors en intérêt et en compréhension.
Dans le cas de mon trajet, il serait intéressant d’avoir les coordonnées du train suivant et précédent. Pour obtenir ce lien entre les trajets et respecter la contrainte HATEOAS, le message devient:
{ "numTrain": 123456789, "departure": {"station": "Bruxelles-Central", "time": "07:28"}, "arrival": {"station": "Liège-Guillemins", "time": "08:23"}, "_links": { "self": { "href": "http://www.triptrain.com/displayTrip?numTrain=123456789&departureStation=Bruxelles-Central&departureTime=07:28" }, "nextTrain": { "href": "http://www.triptrain.com/displayTrip?numTrain=987654321&departureStation=Bruxelles-Central&departureTime=08:01" }, "previousTrain": { "href": "http://www.triptrain.com/displayTrip?numTrain=147258369&departureStation=Bruxelles-Central&departureTime=07:01" } } }
Le bloc de données existant reste inchangé et un bloc de liens a fait son apparition. Les webservices en REST peuvent donc être adaptés sans avoir besoin de toucher à l’existant, le risque de régression est ainsi minimisé.
Le message a maintenant un sens beaucoup plus fonctionnel. A partir d’un trajet, je suis capable de passer au suivant ou au précédent. Je dois avouer que l’exemple est peut-être un peu limité, mais imaginez le principe dans d’autres contextes.
D’une certaine manière, l’API s’auto-découvre et le message s’auto-décrit. La réponse à une requête permet d’en faire une autre sans forcément connaitre à l’avance toutes les méthodes disponibles sur l’API. HATEOAS améliore grandement la lisibilité de vos API, mais l’intérêt devient réel lorsque les consommateurs du webservice utilisent ces nouvelles informations.
Il y a cependant un revers à la médaille: HATEOAS est relativement jeune et la spécification n’est pas clairement définie. D’ailleurs où est-elle? D’autres personnes se sont posé cette question, il semblerait que vous pouvez la trouver ici: HAL – Hypertext Application Language specification. Il y a aussi cette page bien plus lisible et sur laquelle vous trouverez plusieurs liens intéressants dans la partie « Quick links ». Je vous conseille leur lecture si vous souhaitez approfondir le sujet.
Commentaires récents