Quelle est l'utilité / l'importance de REST HATEOAS (niveau de maturité 3)?

110

Je m'implique dans un projet où certains membres de l'équipe senior croient qu'une API REST doit être conforme HATEOAS et implémenter tous les niveaux de maturité de Richardson ( http://martinfowler.com/articles/richardsonMaturityModel.html )!

AFAIK la plupart des implémentations REST ne sont pas compatibles HATEOAS et il devrait y avoir une bonne raison pour laquelle plus de gens ne le font pas. Je peux penser à des raisons telles que la complexité accrue, le manque de cadres (côté serveur et client), le problème des performances et ...

Qu'est-ce que tu penses? Avez-vous eu une expérience avec HATEOAS dans un projet réel?

mhdwrk
la source
Voici un bon article sur le sujet: medium.com/@andreasreiser94 / ... En gros, la façon dont "REST" est normalement implémenté, c'est RPC ...
masterxilo

Réponses:

213

Personne dans la communauté REST ne dit que REST est facile. HATEOAS n'est qu'un des aspects qui ajoute de la difficulté à une architecture REST.

Les gens ne font pas HATEOAS pour toutes les raisons que vous suggérez: c'est difficile. Cela ajoute de la complexité à la fois côté serveur et client (si vous voulez réellement en profiter).

CEPENDANT, des milliards de personnes bénéficient aujourd'hui des avantages de REST. Savez-vous quelle est l'URL de "paiement" sur Amazon? Je ne. Pourtant, je peux commander tous les jours. Cette URL a-t-elle changé? Je ne sais pas, je m'en fiche.

Savez-vous que ça s'en soucie? Quiconque a écrit un écran a gratté le client automatisé Amazon. Quelqu'un qui a probablement reniflé minutieusement le trafic Web, lu des pages HTML, etc. pour trouver quels liens appeler, quand et avec quelles charges utiles.

Et dès qu'Amazon a modifié ses processus internes et sa structure d'URL, ces clients codés en dur ont échoué - car les liens se sont rompus.

Pourtant, les internautes occasionnels ont pu faire leurs achats toute la journée avec à peine un accroc.

C'est REST en action, il est simplement augmenté par l'être humain qui est capable d'interpréter et d'intuitionner l'interface basée sur du texte, de reconnaître un petit graphique avec un panier et de comprendre ce que cela signifie réellement.

La plupart des gens qui écrivent des logiciels ne le font pas. La plupart des gens qui écrivent des clients automatisés s'en moquent. La plupart des gens trouvent plus facile de réparer leurs clients lorsqu'ils se cassent que de concevoir l'application pour ne pas casser en premier lieu. La plupart des gens n'ont tout simplement pas assez de clients là où cela compte.

Si vous écrivez une API interne pour communiquer entre deux systèmes avec un support technique expert et un service informatique des deux côtés du trafic, qui sont capables de communiquer les changements rapidement, de manière fiable et avec un calendrier de changement, alors REST ne vous achète rien. Vous n'en avez pas besoin, votre application n'est pas assez grande et elle n'est pas assez longue pour avoir de l'importance.

Les grands sites avec de grandes bases d'utilisateurs ont ce problème. Ils ne peuvent pas simplement demander aux gens de changer leur code client sur un coup de tête lorsqu'ils interagissent avec leurs systèmes. Le calendrier de développement des serveurs n'est pas le même que le calendrier de développement du client. Les modifications brusques de l'API sont tout simplement inacceptables pour toutes les personnes impliquées, car elles perturbent le trafic et les opérations des deux côtés.

Ainsi, une opération comme celle-ci bénéficierait très probablement de HATEOAS, car il est plus facile à version, plus facile à migrer pour les clients plus âgés, plus facile à rétrocompatible que non.

Un client qui délègue une grande partie de son flux de travail au serveur et agit sur les résultats est beaucoup plus robuste aux changements de serveur qu'un client qui ne le fait pas.

Mais la plupart des gens n'ont pas besoin de cette flexibilité. Ils écrivent du code serveur pour 2 ou 3 départements, c'est un usage interne. Si ça casse, ils le réparent et ils en tiennent compte dans leurs opérations normales.

La flexibilité, qu'elle provienne de REST ou de toute autre chose, engendre la complexité. Si vous voulez que ce soit simple et rapide, alors vous ne le rendez pas flexible, vous «faites-le simplement», et c'est fait. Au fur et à mesure que vous ajoutez des abstractions et des déréférencements aux systèmes, les choses deviennent plus difficiles, plus de plaques chauffantes, plus de code à tester.

Une grande partie de REST échoue à la puce «vous n'en aurez pas besoin». Jusqu'à ce que, bien sûr, vous le fassiez.

Si vous en avez besoin, utilisez-le et utilisez-le tel qu'il est présenté. REST ne fait pas des allers-retours sur HTTP. Cela ne l'a jamais été, c'est un niveau beaucoup plus élevé que cela.

Mais lorsque vous avez besoin de REST et que vous utilisez REST, alors HATEOAS est une nécessité. Cela fait partie du package, et une clé de ce qui le fait fonctionner.

Will Hartung
la source
11
Je pense que vous devriez avoir au moins mille autres likes pour cette réponse. Honnêtement, je dois imaginer que: à quel point est-il important d'être «réel» La question REST revient un peu. Bon sang, je faisais des recherches sur Google juste pour cette raison d'utiliser des munitions lors d'une prochaine réunion lorsque j'ai trouvé ce fil.
nograde
2
merci mon Dieu (ou code), quelqu'un parle aussi des inconvénients de HATEOAS!
IlliakaillI
6
Y a-t-il un autre avantage que la possibilité de changer facilement les URL? Vous ne pouvez pas simplement ajouter de nouvelles options, car contrairement aux humains, le programme ne peut pas fonctionner avec quelque chose de nouveau. De plus, vous êtes simplement passé de la création d'URL connues à la connaissance du nom des actions.
Jimmy T.
Si le consommateur d'API ne sait rien, il ne peut déléguer que des actions utilisateur 1: 1
Jimmy T.
2
En ce qui concerne le changement d'URL, n'oubliez pas que votre client peut utiliser le cache et donc, vous devez garder le comportement sur le serveur pour gérer également l'URL précédente (ou simplement faire une redirection). Comme toute stratégie pour faire évoluer les API, vous devez garder votre ancien comportement opérationnel. HATEOAS n'aide pas beaucoup là-bas.
Bruno Costa
21

Oui, j'ai eu une certaine expérience avec l'hypermédia dans les API. Voici quelques-uns des avantages:

  1. API explorable: cela peut sembler trivial mais ne sous-estimez pas la puissance d'une API explorable. La possibilité de parcourir les données permet aux développeurs clients de construire beaucoup plus facilement un modèle mental de l'API et de ses structures de données.

  2. Documentation en ligne: l'utilisation d'URL comme relations de lien peut diriger les développeurs clients vers la documentation.

  3. Logique client simple: un client qui suit simplement les URL au lieu de les construire lui-même devrait être plus facile à implémenter et à maintenir.

  4. Le serveur s'approprie les structures d'URL: l'utilisation de l'hypermédia supprime la connaissance codée en dur du client des structures d'URL utilisées par le serveur.

  5. Transfert de contenu vers d'autres services: Hypermedia est nécessaire lors du déchargement de contenu vers d'autres serveurs (un CDN par exemple).

  6. Gestion des versions avec des liens: Hypermedia facilite la gestion des versions des API.

  7. Implémentations multiples du même service / API: L'hypermédia est une nécessité lorsque plusieurs implémentations du même service / API existent. Un service pourrait par exemple être une API de blog avec des ressources pour ajouter des articles et des commentaires. Si le service est spécifié en termes de relations de lien au lieu d'URL codées en dur, le même service peut être instancié plusieurs fois à différentes URL, hébergé par différentes sociétés mais toujours accessible via le même ensemble bien défini de liens par un seul client.

Vous pouvez trouver une explication détaillée de ces puces ici: http://soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html

(il y a une question similaire ici: /software/149124/what-is-the-benefit-of-hypermedia-hateoas où j'ai donné la même explication)

Jørn Wildt
la source
Plusieurs implémentations d'un même service: pouvez-vous élaborer? Je ne vois pas comment ça aide.
Abbadon le
J'ai essayé de l'expliquer dans le texte. Aide-t-il?
Jørn Wildt
11

Le niveau de maturité 3 de Richardson est précieux et doit être adopté. Jørn Wildt a déjà résumé certains avantages et une autre réponse, de Wilt, la complète très bien.

Cependant, le niveau de maturité 3 de Richardson n'est pas le même que celui de HATEOAS de Fielding. Le niveau de maturité 3 de Richardson concerne uniquement la conception d'API. HATEOAS de Fielding concerne également la conception d'API, mais prescrit également que le logiciel client ne doit pas supposer qu'une ressource a une structure spécifique au-delà de la structure définie par le type de support. Cela nécessite un client très générique, comme un navigateur Web, qui n'a pas de connaissances sur des sites Web spécifiques. Depuis que Roy Fielding a inventé le terme REST et a défini HATEOAS comme une exigence de conformité à REST, la question est: voulons-nous adopter HATEOAS et sinon, pouvons-nous toujours appeler notre API RESTful ou non? Je pense que nous pouvons. Laisse-moi expliquer.

Supposons que nous ayons atteint HATEOAS. Le côté client de l'application est maintenant très générique, mais très probablement, l'expérience utilisateur est mauvaise, car sans aucune connaissance de la sémantique des ressources, la présentation des ressources ne peut pas être adaptée pour refléter cette sémantique. Si la ressource «voiture» et la ressource «maison» ont le même type de support (par exemple application / json), elles seront présentées à l'utilisateur de la même manière, par exemple sous forme de tableau de propriétés (paires nom / valeur).

Mais bon, notre API est vraiment RESTful.

Supposons maintenant que nous construisions une deuxième application cliente en plus de cette API. Ce deuxième client enfreint les idées HATEOAS et dispose d'informations codées en dur sur les ressources. Il affiche une voiture et une maison de différentes manières.

L'API peut-elle toujours être appelée RESTful? Je le pense. Ce n'est pas la faute de l'API si l'un de ses clients a violé HATEOAS.

Je vous conseille de construire des API RESTful, API à dire pour lequel un client générique peut être mis en œuvre en théorie , mais dans la plupart des cas, vous avez besoin une des informations codées en dur sur les ressources de votre client afin de satisfaire aux exigences de facilité d' utilisation. Néanmoins, essayez de coder en dur le moins possible, pour réduire les dépendances entre le client et le serveur.

J'ai inclus une section sur HATEOAS dans mon modèle d'implémentation REST appelé JAREST .

www.admiraalit.nl
la source
9

Nous construisons une API REST niveau 3 où notre réponse est en HAL-Json. HATEOAS est idéal pour le front et le back-end, mais il comporte des défis. Nous avons fait quelques personnalisations / ajouts pour également gérer ACL dans la réponse HAL-Json (qui ne rompt pas le standard HAL-Json).

Le plus grand avantage de HATEOAS que je vois est que nous n'avons pas besoin d'écrire / deviner les URL sur notre application frontale. Tout ce dont vous avez besoin est un point d'entrée ( https://hostname) et à partir de là, vous pouvez simplement parcourir les ressources en utilisant les liens ou les modèles de liens fournis dans la réponse. Comme ça, le contrôle de version peut être géré facilement, renommer / remplacer les URL, étendre les ressources avec des relations supplémentaires sans casser le code frontal.

La mise en cache des ressources sur le front-end est un jeu d'enfant en utilisant les liens auto. Nous envoyons également des ressources aux clients via une connexion socket, puisque celles-ci sont également rendues en HAL, nous pourrions facilement les ajouter au cache de la même manière.

Un autre avantage de l'utilisation de HAL-Json est qu'il est clair à quoi devrait ressembler le modèle de réponse, car il existe une norme documentée qui doit être suivie.

L' un de nos personnalisations est que nous avons ajouté un objet à l' intérieur des actions de l'objet auto-lien qui expose à l'extrémité avant des actions ou opérations CRUD l'utilisateur authentifié est autorisé à effectuer sur la ressource respective ( create:POST, read:GET, update:PUT, edit:PATCH, delete:DELETE). Comme ça, notre ACL front-end est totalement dictée par notre réponse API REST, déplaçant entièrement cette responsabilité vers le modèle back-end.

Donc, pour donner un exemple rapide, vous pourriez avoir un objet de publication dans HAL-Json qui ressemble à ceci:

{
    "_links": {
        "self": {
            "href": "https://hostname/api/v1/posts/1",
            "actions": {
                "read": "GET",
                "update": "PUT",
                "delete": "DELETE"
            }
        }
    },
    "_embedded": {
        "owner": {
            "id": 1,
            "name": "John Doe",
            "email": "[email protected]",
            "_links": {
                "self": {
                    "href": "https://hostname/api/v1/users/1",
                    "actions": {
                        "read": "GET"
                    }
                }
            }
        }
    },
    "subject": "Post subject",
    "body": "Post message body"
}

Maintenant, tout ce que nous avons à faire sur le front-end est de construire un AclServiceavec une isAllowedméthode qui vérifie si l'action que nous voulons effectuer est dans l'objet actions.

Actuellement sur le front-end, cela semble aussi simple que: post.isAllowed('delete');

Je pense que le niveau REST 3 est excellent, mais cela peut entraîner des maux de tête. Vous aurez besoin d'avoir une grande compréhension de REST et si vous voulez travailler avec REST de niveau 3, je suggérerais de suivre strictement le concept REST, sinon vous vous perdrez facilement en chemin lors de sa mise en œuvre.

Dans notre cas, nous avons l'avantage de construire à la fois le front et le back-end, mais en principe cela ne devrait PAS faire de différence. Mais un piège courant que j'ai vu dans notre équipe est que certains développeurs essaient de résoudre les problèmes front-end (architecture) en modifiant leur modèle back-end pour qu'il "corresponde" aux besoins front-end.

Se flétrir
la source
1
Très bonne réponse. Je pense qu'un exemple aussi pratique était ce que le questionneur initial recherchait.
www.admiraalit.nl
2

J'ai utilisé HATEOAS dans certains projets réels, mais avec une interprétation différente de celle de Richardson. Si c'est ce que veulent vos patrons, alors je suppose que vous devriez le faire. Je considère HATEOAS comme signifiant que vos ressources doivent inclure un doctype HTML, des hyperliens vers des ressources associées et des formulaires HTML pour exposer des fonctionnalités pour les verbes autres que GET. (C'est à ce moment que le type Accept est text / html - les autres types de contenu ne nécessitent pas ces extras.) Je ne sais pas d'où vient la croyance selon laquelle toutes les ressources REST de votre application entière doivent être collées. Une application réseau doit contenir plusieurs ressources qui peuvent ou non être directement liées. Ou pourquoi on pense que XML, JSON et d'autres types doivent suivre cela. (HATEOAS est spécifique au HTML.)

Chris Broski
la source