web-dev-qa-db-fra.com

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

Je m'implique dans un projet où certains membres de l'équipe senior pensent 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 REST ne sont pas conformes à HATEOAS et il devrait y avoir une bonne raison pour que plus de gens ne le fassent pas. ), souci de performance et ...

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

89
mhdwrk

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

Les gens ne font pas de 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 bénéficier).

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

Savez-vous que ça compte? Quiconque a écrit un écran a supprimé le client automatisé Amazon. Quelqu'un qui a probablement soigneusement flairé 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 sans accroc.

C'est REST en action, c'est juste augmenté par l'être humain qui est capable d'interpréter et d'intuitiver l'interface basée sur du texte, de reconnaître un petit graphique avec un panier d'achat et de déterminer 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 qu'il est plus facile de réparer leurs clients lorsqu'ils se cassent que de concevoir l'application pour ne pas se briser en premier lieu. La plupart des gens n'ont tout simplement pas assez de clients là où c'est important.

Si vous écrivez une API interne pour communiquer entre deux systèmes avec un support technique expert et l'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 vous n'achète rien. Vous n'en avez pas besoin, votre application n'est pas assez grande et n'a pas assez longtemps vécu pour être importante.

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 elle est plus facile à mettre à jour, plus facile pour les clients plus âgés à migrer, plus facile à être rétrocompatible qu'improbable.

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 tout usage interne. S'il se casse, ils le réparent, et ils l'ont pris en compte dans leurs opérations normales.

La flexibilité, que ce soit à partir de REST ou toute autre chose, engendre la complexité. Si vous le voulez simple et rapide, alors vous ne le rendez pas flexible, vous le "faites simplement" et vous avez terminé. Lorsque vous ajoutez des abstractions et des déréférencements aux systèmes, les choses deviennent plus difficiles, plus de plaques de chaudière, 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 pousse pas des trucs d'avant en arrière 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 est la clé de ce qui le fait fonctionner.

183
Will Hartung

Oui, j'ai une certaine expérience de l'hypermédia dans les API. Voici quelques 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 créer 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 en tant que 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 URL: l'utilisation d'hypermédia supprime la connaissance codée en dur du client des structures URL utilisées par le serveur.

  5. Déchargement 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 aide à la gestion des versions des API.

  7. Implémentations multiples du même service/API: Hypermedia est une nécessité lorsqu'il existe plusieurs implémentations du même service/API. 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 liens 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 de liens bien défini 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: https://softwareengineering.stackexchange.com/questions/149124/what-is-the-benefit-of-hypermedia-hateoas où j'ai donné la même explication)

19
Jørn Wildt

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

Cependant, le niveau de maturité 3 de Richardson n'est pas le même que 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. Étant donné 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 encore appeler notre API RESTful ou pas? Je pense que nous pouvons. Laissez-moi vous 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 média (par exemple application/json), elles seront alors 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 au-dessus de cette API. Ce deuxième client viole les idées HATEOAS et possède des informations codées en dur sur les ressources. Il présente une voiture et une maison de différentes manières.

L'API peut-elle encore ê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 conseille de construire des API RESTful, c'est-à-dire des API pour lesquelles un client générique peut être implémenté en théorie , mais dans la plupart des cas, vous avez besoin certaines informations codées en dur sur les ressources de votre client afin de satisfaire aux exigences d'utilisation. Essayez tout de même 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 REST appelé JAREST .

9
www.admiraalit.nl

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 également fait quelques personnalisations/ajouts pour gestion de l'ACL à l'intérieur de la réponse HAL-Json (qui ne rompt pas la norme HAL-Json).

Les plus grands avantages de HATEOAS que je vois, c'est que nous n'avons pas besoin d'écrire/de deviner les URL de 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 votre chemin à travers les ressources en utilisant les liens ou les modèles de liens fournis dans la réponse. De cette façon, 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, car celles-ci sont également rendues dans 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 à suivre.

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

Donc, pour donner un exemple rapide, vous pourriez avoir un objet post 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 AclService avec une méthode isAllowed qui vérifie si l'action que nous voulons effectuer se trouve dans l'objet actions.

Actuellement en front-end, il semble aussi simple que: post.isAllowed('delete');

Je pense que REST niveau 3 est génial, mais cela peut entraîner des maux de tête. Vous aurez besoin d'avoir une bonne compréhension de REST et si vous voulez travailler) avec le niveau 3 REST je suggère de suivre strictement le concept REST sinon vous vous perdrez facilement sur votre 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 écueil commun que j'ai vu dans notre équipe est que certains développeurs essaient de résoudre les problèmes frontaux (architecture) en changeant leur modèle principal afin qu'il "réponde" aux besoins frontaux.

4
Wilt

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 suppose que HATEOAS signifie que vos ressources doivent inclure un doctype HTML, des hyperliens vers des ressources connexes et des formulaires HTML pour exposer les fonctionnalités des verbes autres que GET. (C'est lorsque le type Accept est text/html - les autres types de contenu ne nécessitent pas ces extras.) Je ne sais pas où la croyance que toutes les ressources REST de votre application entière doivent doivent être collées ensemble. 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.)

2
Chris Broski