Qu'est-ce que HATEOAS offre pour la découvrabilité et le découplage en plus de la possibilité de changer plus ou moins librement la structure de votre URL?

62

Dernièrement, j'ai lu quelque chose sur Hypermedia en tant que moteur d'état d'application (HATEOAS), la contrainte prétendue pour rendre une API Web "vraiment RESTful". Cela revient essentiellement à inclure des liens avec chaque réponse aux transitions possibles que vous pouvez effectuer à partir de l'état actuel.

Laissez-moi illustrer ce que HATEOAS est basé sur ma compréhension - et corrigez-moi s'il vous plaît si je rate quelque chose.

/
    GET: {
        "_links": {
            "child": [
                { "href": "http://myapi.com/articles", "title": "articles" }
            ]
        }
    }

/articles?contains=HATEOAS
    GET: {
        "_items": [
            { "uri": "http://myapi.com/articles/0", "title": "Why Should I Care About HATEOAS?" },
            { "uri": "http://myapi.com/articles/1", "title": "HATEOAS: Problem or Solution?" }
        ],
        "_links": {
            "self": { "href": "http://myapi.com/articles", "title": "articles" },
            "parent": { "href": "http://myapi.com/", "title": "home" }
        }
    }

    POST: {
        "title": "A New Article",
        "body": "Article body",
        "tags": [ "tag1", "tag2" ]
    }

/articles/0
    GET: {
        "title": "Why Should I Care About HATEOAS?",
        "body": "Blah blah blah"
        "tags": [ "REST", "HATEOAS" ],
        "_links": {
            "self": { "href": "http://myapi.com/articles/0", "title": "article" },
            "parent": { "href": "http://myapi.com/articles", "title": "articles" }
        }
    }

HATEOAS aurait deux avantages majeurs:

  1. L'ensemble du service est découvrable à partir de l'URI racine, la documentation n'est plus nécessaire.

  2. Le client est découplé du serveur, ce qui permet désormais de modifier librement la structure de l'URI. Cela élimine le besoin de versioning de l'API.

Mais à mon avis, un service est beaucoup plus que sa structure d'URI. Pour l'utiliser efficacement, vous devez également connaître:

  • quels paramètres de requête vous pouvez utiliser et leurs valeurs possibles
  • la structure du fichier JSON / XML / quels que soient les documents à envoyer dans vos demandes POST / PATCH / etc
  • la structure de la réponse envoyée par le serveur
  • les erreurs possibles qui pourraient se produire
  • ...

Basé sur ce qui précède, HATEOAS ne résout qu'une infime partie des problèmes de découverte et de couplage. Vous devez toujours documenter les quatre aspects ci-dessus et les clients seront toujours fortement couplés au serveur à cause d'eux. Pour éviter de casser des clients, vous devez toujours mettre à jour votre API.

Le seul avantage qu'il offre est que vous pouvez modifier votre structure d'URL plus ou moins librement (soit dit en passant, que s'est-il passé avec le principe "Les URI cool ne changent pas" ?). Ma compréhension est-elle correcte?

Botond Balázs
la source

Réponses:

47

Je pense que votre instinct est en grande partie correct; ces avantages proclamés ne sont pas vraiment géniaux, car pour toute application Web non triviale, les clients vont devoir se soucier de la sémantique de ce qu'ils font ainsi que de la syntaxe.

Mais cela ne signifie pas que vous ne devez pas faire en sorte que votre demande respecte les principes de HATEOAS!

Qu'est-ce que HATEOAS signifie vraiment ? Cela signifie structurer votre application de manière à ce qu’elle ressemble en principe à un site Web et que toutes les opérations que vous souhaitez effectuer puissent être découvertes sans avoir à télécharger un schéma complexe. (Les schémas WSDL sophistiqués peuvent tout couvrir, mais au moment où ils le font, ils dépassent les capacités de pratiquement tous les programmeurs de comprendre, et encore moins d'écrire! Vous pouvez voir HATEOAS comme une réaction face à une telle complexité.)

HATEOAS ne signifie pas seulement des liens riches. Cela signifie utiliser les mécanismes d'erreur du standard HTTP pour indiquer plus précisément ce qui n'a pas fonctionné. vous ne devez pas simplement répondre avec «waaah! non »et peut à la place fournir un document décrivant ce qui était réellement faux et ce que le client pourrait faire à ce sujet. Cela implique également de prendre en charge des éléments tels que les demandes OPTIONS (moyen standard permettant aux clients de déterminer les méthodes HTTP qu’ils peuvent utiliser) et la négociation du type de contenu afin que le format de la réponse puisse être adapté à un formulaire que les clients peuvent gérer. Cela signifie mettre dans un texte explicatif(ou, plus probablement, des liens vers celui-ci) afin que les clients puissent rechercher comment utiliser le système dans des cas non triviaux s’ils ne le savent pas; le texte explicatif peut être lisible par l'homme ou par machine (et peut être aussi complexe que vous le souhaitez). Enfin, cela signifie que les clients ne synthétisent pas de liens (sauf pour les paramètres de requête); les clients n'utiliseront un lien que si vous le leur dites.

Vous devez penser à faire naviguer le site par un utilisateur (qui peut lire JSON ou XML au lieu de HTML, donc un peu étrange) avec une grande mémoire pour les liens et une connaissance encyclopédique des normes HTTP, mais sinon aucune connaissance de ce qu'il faut faire. faire.

Et bien sûr, vous pouvez utiliser la négociation de type de contenu pour servir un client HTML (5) / JS qui leur permettra d'utiliser votre application, si c'est ce que leur navigateur est prêt à accepter. Après tout, si votre API RESTful est bonne, cela devrait-il être «trivial» à implémenter?

Donal Fellows
la source
6

En réalité, HATEOAS doit comporter un deuxième pilier définissant une API RESTful: type de support normalisé. Dit Roy

Une API REST devrait consacrer la quasi-totalité de ses efforts descriptifs à la définition du ou des types de support utilisés pour représenter les ressources ".

Avec un type de support standardisé définissant la transition de manière explicite et un lien hypertexte permettant de pointer les ressources les unes vers les autres, vous pouvez créer un graphe de ressources pouvant prendre n’importe quelle forme sans détruire aucun client. Comme le travail Web, en réalité: vous avez un lien entre les documents, et les documents sont écrits en HTML qui définissent comment suivre ces liens. <a href>est un GET, <form>est GET ou POST (et définit le modèle d'URL à utiliser dans le cas de GET), <link type="text/css">est GET, etc. C'est ainsi que les navigateurs peuvent naviguer dans des pages HTML structurées arbitraires et sur le Web.

Tout ce que vous avez dit

  • quels paramètres de requête vous pouvez utiliser et leurs valeurs possibles
  • la structure du fichier JSON / XML / quels que soient les documents à envoyer dans vos demandes POST / PATCH / etc
  • la structure de la réponse envoyée par le serveur
  • les erreurs possibles qui pourraient se produire

Sont des points qui devraient être adressés par la définition de votre type de média standardisé . Bien sûr, c'est beaucoup plus difficile et ce n'est pas quelque chose auquel la plupart des gens pensent lorsqu'ils définissent une API "REST". Vous ne pouvez pas simplement prendre vos entités commerciales et insérer leurs attributs dans un document JSON pour obtenir une API RESTful.

Bien sûr, ce qui s’est passé est que REST a en quelque sorte été dilué pour signifier "utiliser HTTP au lieu de compliqué SOAPy thingy". Utiliser simplement HTTP et HyperText ne suffit pas pour être RESTful, c'est ce à quoi la plupart des gens se trompent.

Ce n’est pas nécessairement une mauvaise chose: REST sacrifie performance et facilité de développement en échange d’une maintenabilité et d’une évolutivité à plus long terme. Il a été conçu pour l'intégration d'applications de grandes entreprises. Une petite API Web avec une structure JSON codée en dur peut être ce dont vous avez besoin. Il suffit de ne pas l'appeler REST, c'est une API Web ad-hoc, rien de plus. Et ça ne veut pas dire que ça craint, ça veut juste dire que ça n'essaie pas de suivre la contrainte de REST.

Lectures complémentaires

J'espère que cette aide clarifie un peu :)

Laurent Bourgault-Roy
la source
2

Certains formats Hypermedia s'efforcent de fournir des réponses plus riches, qui incluent plus d'informations sur le type de demandes à envoyer, et rien ne vous empêche d'enrichir la réponse avec encore plus d'informations.

Voici un exemple de document Siren :

{
  "class": [ "order" ],
  "properties": { 
      "orderNumber": 42, 
      "itemCount": 3,
      "status": "pending"
  },
  "entities": [
    {
      "class": [ "info", "customer" ],
      "rel": [ "http://x.io/rels/customer" ], 
      "properties": { 
        "customerId": "pj123",
        "name": "Peter Joseph"
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
      ]
    }
  ],
  "actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": "application/x-www-form-urlencoded",
      "fields": [
        { "name": "orderNumber", "type": "hidden", "value": "42" },
        { "name": "productCode", "type": "text" },
        { "name": "quantity", "type": "number" }
      ]
    }
  ],
  "links": [
    { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
    { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
    { "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

Comme vous pouvez le constater, actionsle message contient des informations sur la procédure à suivre pour appeler. Ensuite, en interprétant ces informations, le client devient plus résistant aux changements.

Cela devient particulièrement puissant si rels sont des URI qui peuvent être recherchés, plutôt que d'un vocabulaire fixe.

mcintyre321
la source
0

Où avez-vous lu que "la documentation n'est plus nécessaire" pour les services HATEAOS? Comme vous le dites, vous devez toujours documenter la sémantique des liens. Cependant, avec HATEOAS, vous n'avez pas besoin de documenter, et donc de conserver à jamais, la structure de la plupart des URI.

HATEOAS permet à un implémenteur de services de modifier et de dimensionner l’implémentation de manière significative et efficace sans modifier un petit ensemble d’URI dont dépend le client. Il est plus facile de garder un petit nombre de points d’entrée inchangé qu’un grand ensemble. Par conséquent, la réduction du nombre de points d’entrée publics au service et la fourniture dynamique de liens vers des sous-ressources (HATEOAS) prennent en charge «les URI frais ne changent pas» mieux que les services non-HATEOAS.

Jonathan Giddy
la source
Un endroit où l'on peut lire que "la documentation n'est plus nécessaire" est la thèse de Roy Fielding, qui a inventé le terme.
meriton - en grève le
1
Je viens de chercher dans la thèse de Fielding des utilisations de "documentation" et je n'ai rien trouvé qui ressemble à l'énoncé "la documentation n'est plus nécessaire". Pouvez-vous s'il vous plaît indiquer où dans la thèse de Fielding vous avez trouvé cette revendication?
Jonathan Giddy
0

(HATEOAS), la contrainte censée rendre une API Web "vraiment RESTful"

La seule chose qui en fait une véritable API REST est de répondre à toutes les contraintes, pas à une seule.

Mais à mon avis, un service est beaucoup plus que sa structure d'URI. Pour l'utiliser efficacement, vous devez également connaître: ...

C'est pourquoi nous avons besoin des autres contraintes, du message auto-descriptif, etc.

Pour éviter de casser des clients, vous devez toujours mettre à jour votre API.

Peu importe comment vous essayez, vous aurez besoin de la version de votre API. Dans un client REST, vous devez toujours savoir comment accéder à une page sur laquelle vous souhaitez effectuer des tâches, quels liens suivre et quelles propriétés vous devez collecter en fonction du vocabulaire RDF décrivant le message. Si vous devez remplacer ou supprimer quelque chose de ce vocabulaire, tous vos clients seront probablement cassés et vous aurez besoin d'une nouvelle version. Je pense donc que REST n'est pas quelque chose que vous devriez publier tôt (et comprendre le modèle pendant que vous changez constamment l'API), sinon vous aurez plusieurs versions. Vous devez d'abord disposer d'un modèle de domaine stable sur lequel vous pouvez construire ...

inf3rno
la source