Bonjour,
Aujourd’hui, je veux vous parler du niveau de maturité de maturité de communication de webservices rest : hateoas.
Cet article fera volontairement des raccourcis et sera vulgarisé.
Tout d’abord, il faut faire un petit résumé rapide sur les webservices.
Les webservices
L’objectif d’un webservice est de permettre la communication entre deux machines sans qu’elles ne sachent quel langage de programmation chacune utilise.
Par exemple, un serveur java peut communiquer avec un serveur php sans que ça pose de problème. Le serveur qui met à disposition le webservice va dire ce qu’il attend en entrée comme format (XML pour la norme SOAP par exemple), les informations qui devront être obligatoirement renseignées, celles qui sont facultatives, etc. En sortie, il renverra un fichier, qui lui aussi qui sera normé.
Il existe deux normes de webservice : SOAP (basé sur les fichiers XML) et REST (basé sur le protocole HTTP).
L’avantage du REST est qu’il peut directement appelé par un navigateur web.
Les développeurs se sont dit : « hé, si on peut appeler les webservices REST depuis un navigateur, il y a moyen de développer une application web qui serait basé que sur des webservices REST. Et non plus des controleurs web d’un coté et webservices de l’autre. »
Et oui, avant on devait faire un controleur web qui renvoyait, par exemple, une page d’affichage de données et si un serveur distant devait également avoir accès à ces mêmes données, on devait faire un webservice qui lui renvoyait. Maintenant, on peut faire un seul et même point d’entrée : le webservice REST qui pourra renvoyer les données aussi bien au navigateur qu’à un autre serveur.
Oui, mais on doit pouvoir donner des informations sur les échanges entre les machines.
Si mon navigateur envoie des données qui ne sont pas attendues par le webservice, ce dernier doit pouvoir lui dire qu’il y a eu un problème.
C’est là qu’intervient les différents niveaux de maturité des webservices.
Les maturités des API webservices
Niveau 0
Dans ce niveau, le plus bas, tout se passe en POST (signifie normalement qu’on envoie des données au serveur) sur une même url et le serveur répondra toujours 200 (code pour OK), que la requête se soit bien passée ou non.
Le problème est que pour afficher des données, le POST ne sert à rien; et le code 200 renvoyé, quelque soit le vrai état de la requête coté serveur, n’est pas satisfaisant car ça peut cacher une erreur.
Niveau 1
Avec ce niveau, on appelle toujours le serveur en POST, mais là on va enrichir l’url en lui disant par exemple quel objet on cherche à avoir.
Ex, si on veut récupérer l’utilisateur 42, l’url sera du type :
www.monsupersite.fr/user/42
Si on cherche à avoir le produit 12, l’url sera du type :
www.monsupersite.fr/product/12
Si on veut avoir tous les utilisateurs, l’url sera du type :
www.monsupersite.fr/users
Ainsi, on voit que l’url commence à « dessiner » ce qu’on fait réellement sur le site.
Niveau 2
Là, en plus d’avoir des url différentes suivant ce qu’on fait, on demande au serveur des données d’affichage avec le mot GET, l’ajout d’un nouvel élément avec le code PUT, la modification avec POST et la suppression avec DELETE.
Le serveur en retour répondra avec un code différencié du style : 201 pour dire que la création s’est bien passée, 404 pour dire que la ressource n’a pas été trouvée, etc.
Niveau 3 : hateoas
L’objectif de ce niveau est d’en plus d’avoir un échange verbeux entre les machines (niveau 2, pour rappel), permet aussi d’envoyer des liens vers d’autres webservices liés à l’action qu’on vient de faire.
Par exemple, si on veut récupérer les informations d’un utilisateur, on fera :
Appel en GET vers l’url : www.monsupersite.fr/user/42
Le serveur renvoie 200 et en plus des liens vers le webservice qui liste les produits achetés par ce même utilisateur.
Le retour est du style :
[
{
"user" : {
"id" : 42,
"name" : "toto",
"email" : "toto@monsupersite.fr",
"links" : [
{
"rel" : "self",
"href" : "http://www.monsupersite.fr/user/42"
}
],
"products" : {
"links" : [
{
"rel" : "self",
"href" : "http://www.monsupersite.fr/user/42/products"
}
]
}
}
}
]
Ainsi, en plus d’avoir les informations liées à l’utilisateur directement, nous avons aussi le lien vers le webservice qui permettra de récupérer les produits achetés par ce même utilisateur.
Il peut bien sur avoir plus d’une sous partie dans le résultat renvoyé par le serveur.
Comme il s’agit d’un degré de maturité proposé par une personne, Leonard Richardson, il ne s’agit pas d’un standard. Donc chacun peut faire ce qu’il veut.
A mon sens, l’intérêt de Hateoas est d’autant plus important si on l’utilise dans le cadre d’une application basée sur l’architecture microservices (qui sera expliqué dans le prochain article).