Accueil Nos publications Blog HATEOAS ou Hypermedia API

HATEOAS ou Hypermedia API

virtual_links-256

Concevoir, mettre en œuvre et maintenir des API Web est plus qu’un défi ; pour de nombreuses entreprises, c’est un impératif. Mais, malheureusement, dans l’implémentation de ces APIs, l’hypermédia est la contrainte la moins utilisée ! Pourtant, c’est la plus présente sur le web ! Je vous propose de découvrir ensemble de quoi il retourne…

HATEOAS, c’est quoi ? Et quelles sont ses Origines ?

HATEOAS, pour Hypermedia As The Engine Of Application State, n’est pas un nouveau concept, puisqu’il est apparu en tant que contrainte pour le style d’architecture REST. Mais avant de feuilleter nos spécifications, il est nécessaire de se rappeler de quelques notions essentielles :

Le Protocole HTTP 

HTTP (Hypertext Transfert Protocol) est un protocole qui gère la communication entre plusieurs hosts distribués via des liens. Ce protocole est la base de toutes les applications web, et tout ce dont un tiers à besoin pour communiquer avec un autre tiers, c’est un lien (URI).

Ensuite, HTML 

HTML (Hypertext Markup Language) est généralement réservé pour représenter les “pages web”, les données visuelles et non techniques. Ce dernier dispose des éléments nécessaires qui composent le principe de l’Hypermedia comme <a href>, les “rel” et les <ul></ul>…

Dessin sans titre (5)

Quand vous visitez un site web, tout ce que vous avez besoin de connaître, c’est l’URL de la page d’accueil. Vous n’avez pas besoin d’une documentation pour naviguer dans le site, tous les autres liens permettant la navigation à l’intérieur de site web seront fournis dans la réponse de la page d’accueil.

Et pour finir, le REST de Roy Thomas Fielding 

Le HATEOAS (Hypermedia As The Engine Of Application State) est une des contraintes fondamentales du style d’architecture REST, tel que défini dans le Chapitre 5 de la thèse de doctorat de Roy T. Fielding(le papa du REST) en 2000.

In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.

Roy T. Fielding
(Architectural Styles and the Design of Network-based Software Architecures – Chapter 5)

Souvenez-vous des 6 contraintes de base de ce fameux style d’architecture :

1 – Client-Server

2- Stateless Server (Serveur sans état)

3 – Cache

4 – Uniform Interface (Une interface uniforme)

      4.1 – Identification of resources (Identification des ressources)

      4.2 – Manipulation of resources through representations (Manipulation des ressources à travers les représentations)

      4.3 – Self-descriptive messages (Un message auto-descriptif)

      4.4 – Hypermedia as the engine of application state (HATEOAS)

5 – Layered System (Un système hiérarchisé par couche)

6 – Code-On-Demand

HATEOAS, Principe de fonctionnement

Pour bien utiliser l’HATEOAS, il est important de comprendre deux principes essentiels que sont les URLs Immutables, ou les liens qui retournent toujours les mêmes ressources, et la navigation API, ou la modélisation en arbres avec des transitions entre les différents states au sein d’une API Web. Les states sont les pages web et les transitions sont les liens hypertextes. Ce principe est bien clair dans le chapitre 6 de la thèse de Fielding :

 

The name ‘Representational State Transfer’ is intended to evoke an image of how a well-designed Web application behaves: a network of web pages (a virtual state-machine), where the user progresses through the application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use.

Roy T. Fielding
(Architectural Styles and the Design of Network-based Software Architecures – Chapter 6)

 

L’API Hypermedia est donc considéré comme une virtuelle state-machine,  qui ne nécessite ni une définition, ni un document formel afin de naviguer à l’intérieur. Il suffit de connaître l’adresse de la page d’accueil, et le reste des states (des pages) seront explorées via les liens hypertexte.

Donc, l’idée derrière le HATEOAS est très simple. Pour chaque réponse du serveur, nous incluons des liens vers les prochaines requêtes pour explorer les autres ressources. Prenons l’exemple d’une réponse JSON d’un serveur suite à une requête de récupération des utilisateurs (Réponse classique non-HATEOAS).

[
    {
        "uid": 1,
        "age": 18,
        "name": "John Doe",
        "order": 1
    },
    {
        "uid": 2,
        "age": 29,
        "name": "Bob Marley",
        "order": 2
    }
]

Et si un client qui consomme cet API veut en savoir plus sur les utilisateurs ? Doit-il préparer à l’avance ses URLs qui mènent vers les ressources de détails de chaque utilisateur ? Et si l’API évolue au cours du temps et les URLs changent ? Que faire ?

La solution serait donc que l’API fournisse au client des liens dans la réponse, semblables à des hyperlinks dans un site web (c.f HTML). Un premier avantage est que le client sera complètement dissocié de l’API de service et qu’il n’a pas à hard-coder les URLs pour interagir avec l’API et l’application state.

[
    {
        "uid": 1,
        "age": 18,
        "name": "John Doe",
        "order": 1,
        "href": "/user/1"
    },
    {
        "uid": 2,
        "age": 29,
        "name": "Bob Marley",
        "order": 2,
        "href" : "/user/2"    
    }
]

C’est exactement la même réponse qu’avant, mais avec un champ href en plus, contenant un lien direct vers les ressources détails d’un utilisateur. Donc, avec cette idée, nous venons d’implémenter un des concepts fondamentaux de HATEOAS.

Combien de liens faut-il avoir au minium pour respecter la contrainte HATEOAS ?

Au minimum, 1 lien.

Maintenant, supposons que notre réponse JSON contient un ensemble de liens href, qui mènent par exemple vers les fiches détails, les commentaires et les mentions j’aime de chaque utilisateur, comme suit :

    {
        "uid": 2,
        "age": 29,
        "name": "Bob Marley",
        "order": 2,
        "href" : "/user/2",
        "comments-href" : "/user/2/comments",
        "likes-href" : "/user/2/likes"
    }
Ok tous ça c’est bien, mais est-ce que les clients doivent se rappeler de toutes ces URLs ?

Le client n’a pas à se rappeler des valeurs des urls, notamment quand l’API utilise les URLs immutables qui changent à chaque révision. La solution est donc d’ajouter des informations supplémentaires dans notre réponse JSON via les attributs rel qui ont comme tâche de nommer les URLs. Un exemple très connu pour les rel dans HTML est stylesheet, pour faire la liaison avec l’URL d’un fichier de style CSS. Cela nous donne une réponse de la forme :

    {
        "uid": 2,
        "age": 29,
        "name": "Bob Marley",
        "order": 2,
        "links" : [
                    {
                        "href" : "/user/2",
                        "rel" : "self"    
                    },
                    {
                        "href" : "/user/2/comments",
                        "rel" : "comments"
                    },
                    {
                        "href" : "/user/2/likes",
                        "rel" : "likes"
                    }
                  ]   
    }

Ainsi, notre réponse embarque toutes les URLs permettant d’explorer l’API pour un utilisateur, et l’attribut rel permet de donner un sens aux URLs et de faciliter la gestion côté client. Nous pouvons ajouter bien entendu d’autres attributs pour documenter l’API comme l’attribut desc qui fournit une description de chaque URL.

Les URLs Immutables et les Redirect HTTP 

Les API Hypermedia se basent généralement sur les Links ou les URL immutables, (Create and never update). Une URL immutable renvoie toujours la même ressource et, à chaque fois qu’une ressource évolue ou change, le numéro de révision à la fin de l’URL s’incrémente ou l’URL change :

 "href" : "/user/2/comments<strong>;fa5457fa</strong>",

Et c’est donc impossible pour un client de se rappeler des URL d’où l’intérêt d’utiliser les attributs “rel” aussi.

Et si un client appelle une URL qui n’existe plus, quelle sera la réponse ?

Le protocole HTTP est conçu pour supporter les URLs immutables, et il existe plusieurs solutions pour gérer le changement des URLs, comme les redirect du protocole HTTP, qui redirigent le client vers la nouvelle ressource avec le status code 302. La nouvelle adresse sera dans le header Location (mécanisme natif dans les clients HTTP)

Requête Client:

GET /index.html HTTP/1.1
Host: www.host-sample.com

Réponse Serveur:

HTTP/1.1 302 Found
Location: https://www.soat.fr/posts/samples/

HATEOAS, Les avantages

Une API qui se base sur les liens hypermédia adopte plusieurs avantages comme :

  • L’abstraction entre le client et l’API de service
  • Evolution de l’API de service sans impacter les clients existants
  • Alléger le code côté client (pas de nomenclature imposée des URLs)

HATEOAS, Les inconvénients

Le HATEOAS présente aussi quelques inconvénients mineurs, comme :

  • Une API Hypermedia dépasse la simple sérialisation / dé-sérialisation et qui est donc plus compliquée à développer

Quelques implémentations

HATEOAS est présent depuis 15 ans. Pour les implémentations, on ne trouve pas vraiment beaucoup des frameworks matures qui l’intègrent, mais voici quelques implémentations HATEOAS :

  • Spring HATEOAS
  • Jersey API
  • Yii 2 framework
  • Tastypie

Conclusion

De nos jours, toutes les Web UI (les sites web) adhèrent au concept de HATEOAS. Cependant, toutes les web APIs, même les plus populaires, violent ce principe, malgré les avantages et le confort qu’il offre au client. Avec la révolution dans le monde connecté, et l’essor des applications réactives, avec leurs contraintes de scalabilité, les architectes s’orientent de plus en plus vers des solutions HATEOAS, plutôt que vers des APIs REST pragmatiques classiques, ou encore SOAP.

Plus en détails…