43 votes

Fractionner les poils avec REST: Une API JSON REST standard est-elle contraire à HATEOAS?

Je faisais un peu de lecture sur le REPOS ce matin et je suis tombé sur le HATEOAS principe ("hypermédia comme le moteur de l'état de l'application").

Citant le RESTE page de Wikipédia:

Les Clients à faire les transitions de l'état uniquement à travers des actions qui sont identifiés de manière dynamique au sein de l'hypermédia par le serveur (par exemple, par des liens hypertextes à l'intérieur de l'hypertexte). Sauf pour de simples fixe de points d'entrée pour l'application, un client n'a pas supposer que des actions particulières seront disponibles pour n'importe quel particulier de ressources au-delà de celles décrites dans les représentations précédemment reçu du serveur.

Et Roy Fielding du blog:

...si le moteur de l'état de l'application (et donc de l'API) n'est pas animé par l'hypertexte, alors il ne peut pas être tranquille et ne peut pas être une API REST. Période.

J'ai lu ce que: Le client ne peut demander que des modifications de l'état sur la base des actions disponibles à partir du corps de la réponse du serveur (l'hypertexte).

Dans un HTML monde, cela fait beaucoup de sens. Le client doit seulement être en mesure de demander des modifications de l'état (les nouvelles actions/pages), basé sur les liens mis à disposition par l'intermédiaire de l'hypertexte (HTML).

Lorsque la ressource est représentée par d'autres moyens, tels que JSON, XML, YAML, etc. Ce n'est pas si évident.

Prenons un exemple de "REPOS" API JSON:

J'ai créer une nouvelle ressource (un commentaire par exemple) par l'envoi d'une requête POST

/comments.json? # with params...

Le serveur répond avec:

# Headers
HTTP/1.1 201 Created 
Location: http://example.com/comments/3
Content-Type: application/json; charset=utf-8
... Etc.

# Body
{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}

Je sais que je peux maintenant accéder à ce commentaire à l'URI de retourné dans l'en-tête: http://example.com/comments/3.json

Lorsque je visite http://example.com/comments/3.json je vois:

{"id":3,"name":"Bodacious","body":"An awesome comment","post_id":"1"}

Supposons que l'API de la documentation me dit que je peux supprimer ce commentaire par l'envoi d'une demande de SUPPRESSION à la même URI. C'est assez commun parmi les "REPOS" Api.

Cependant:

La réponse du serveur à l' GET http://example.com/comments/3.json ne me dit rien au sujet d'être en mesure de supprimer le commentaire par l'envoi d'une demande de SUPPRESSION. Tous il me montre la ressource.

Que je peux aussi SUPPRIMER un commentaire avec la même URL est quelque chose que le client sait par out-of-band de l'information (la documentation) et n'est pas découvert et piloté par la réponse du serveur.

Ici, le client est en supposant que la SUPPRESSION de l'action (et d'autres) sont disponibles pour cette ressource, et cette information n'a pas été précédemment reçu du serveur.

Ai-je mal compris HATEOAS ou suis-je en droit de dire qu'une API correspondant à la description ci-dessus ne serait pas, au sens strict, être une API REST?

Je suis conscient adhère à 100% RESTE n'est pas toujours possible, ni la manière la plus pragmatique pour aller. J'ai posté cette question purement pour satisfaire ma propre curiosité à propos de la théorie derrière le REPOS, et non pas pour obtenir des conseils sur le monde réel des meilleures pratiques.

20voto

curtisdf Points 2167

Jon Moore a donné un excellent exposé en Novembre 2010 sur les écrous et boulons de la rédaction d'un vraiment Reposante (c'est à dire HATEOAS) de l'API et le client. Dans la première partie, il propose le JSON n'est pas un bon type de support pour le REPOS car il manque de communément compris façon de représenter les liens et pris en charge les méthodes HTTP. Il soutient que le bon vieux XHTML est en fait parfait pour ça depuis des outils pour l'analyse (par exemple XPath) sont facilement accessibles, il prend en charge les formulaires (pensez à OBTENIR un lien de template et PUT, POST et DELETE méthodes) et, bien entendu, d'identifier les liens hypertexte, plus quelques autres avantages principalement la capacité à utiliser l'API avec n'importe quel navigateur web standard (facilite l'emploi pour les développeurs, l'assurance qualité et le personnel de soutien.)

L'argument que j'avais toujours fait avant de regarder son discours, c'est que JSON est donc beaucoup plus faible de la bande passante des consommateurs que toute *ML de la langue ex: XML, HTML, XHTML. Mais en utilisant laconique XHTML si possible, tels que des liens relatifs plutôt qu'absolus, ceux (allusion à, mais pas de façon évidente dans l'exemple qu'il utilise tout au long de son discours), et en utilisant la compression gzip, cet argument perd beaucoup de poids.

Je me rends compte des efforts tels que JSON Schema et d'autres RFC sont en cours pour essayer de normaliser les choses en JSON, mais en attendant, Moore parler m'a convaincu de faire XHTML essayer.

18voto

suing Points 1118

JSON comme un hypermédia type n'est pas de définir un identifiant pour un flux d'application. HTML a lien et de la forme de balise qui guide l'utilisateur à travers un processus.

Si votre demande ne concerne PUT, POST, DELETE, OBTENIR sur une ressource, votre documentation pourrait facilement expliquer.

Cependant, si c'était plus compliqué, comme l'ajout d'une réplique à un commentaire et que la réfutation est une autre ressource, alors le commentaire que vous auriez besoin de l'hypermédia type qui guide le consommateur créer la réfutation.

Vous pouvez utiliser le HTML/XHTML, Créer votre propre "bodacious+json" ou d'utiliser quelque chose d'autre. Voici tous les différents types de médias http://www.iana.org/assignments/media-types/index.html

Je suis l'aide de HAL et il a un joli groupe actif. Voici des liens vers elle.

http://www.iana.org/assignments/media-types/application/vnd.hal+json

http://stateless.co/hal_specification.html

Le livre "la Construction de l'Hypermédia Api avec le HTML5 et le Nœud" va en profondeur dans l'hypermédia et les types de médias. Il montre comment créer un type de support pour un particulier ou d'usage général en XML ou JSON.

16voto

simony Points 146

Une bonne solution serait d'utiliser le Permettre-d'en-tête d'informer le client des méthodes disponibles/actions:

> GET /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 200 OK
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<
< {
<  "name": "Bodacious",
<  "body": "An awesome comment",
<  "id":   "1",
<  "uri": "/posts/1/comments/1"
< }

La mise en service de la thèse définit deux types de métadonnées: représentation des métadonnées; et les métadonnées de ressources.

L'Autoriser à en-tête de HTTP/1.1 fonctions comme les métadonnées de ressources , car il décrit une propriété d'une ressource; c'est à dire les méthodes qu'il permet.

En utilisant pleinement les fonctionnalités fournies par HTTP élimine le besoin pour n'importe quel hors-de-tenu de l'information, et de devenir plus Reposant.

HATEOAS dans un simple contexte HTTP décrit la façon dont un client peut naviguer à partir d'une représentation à l'autre en suivant les Uri à l'aide de l'OBTENIR, alors que le Permettent-d'en-tête informe le client des méthodes supplémentaires pris en charge par la ressource qui a généré la représentation.

C'est une conception soignée; le client a demandé une représentation, et en outre reçu tout un tas de métadonnées supplémentaires sur la ressource qui permet à l'efficacité de demander des observations supplémentaires.

Je pense que la citation que vous avez de la Wikipedia RESTE de la page est un peu trompeur dans le choix de ses mots et n'a pas aidé ici (N. B. Il a été amélioré depuis que cette question a été posée).

Tous les clients HTTP supposer qu'une méthode est susceptible d'être disponible pour la majorité des ressources. Ils font cela parce que le soutien pour l'OBTENIR et la TÊTE sont les exigences minimales pour un HTTP/1.1 serveur. Sans cette hypothèse, le web ne serait pas la fonction. Si un client peut supposer OBTENIR est disponible, alors pourquoi ne pas en faire d'autres hypothèses sur la commune de méthodes telles que SUPPRIMER, ou de la POSTE?

REPOS et HTTP but est de tirer parti du pouvoir de faire des hypothèses sur un ensemble de base de méthodes afin de réduire le volume global de la demande sur un réseau; si une demande réussit il n'y a pas besoin de communiquer davantage; mais si la demande échoue avec le statut "405 method not Allowed", le client est immédiatement à la réception de la demande qui pourrait réussir via le Permettre-d'en-tête:

> ANNIHILATE /posts/1/comments/1 HTTP/1.1
> Content-Type: application/json
>
< HTTP/1.1 405 Method Not Allowed
< Allow: HEAD, GET, DELETE
< Content-Type: application/json
<

Si l'ensemble de base de HTTP/1.1 méthodes ne sont pas assez, alors vous êtes libre de définir vos propres. Cependant, il serait Reposant à résoudre des problèmes en utilisant les fonctions disponibles de HTTP avant de définir de nouvelles méthodes ou de mettre des métadonnées dans le message du corps.

8voto

DaveGauer Points 566

Entièrement découvrable API JSON qui ne nécessite pas d'out-of-band de connaissances que vous le mettez donc en quelques mots:

"Que je peux aussi SUPPRIMER un commentaire avec la même URL est quelque chose que le client sait par out-of-band de l'information (la documentation) et n'est pas découvert et piloté par la réponse du serveur."

...est tout à fait possible. Il nécessite juste un standard et un client qui comprend la norme. Découvrez hm-json et le hm-json projet de Navigateur:

https://bitbucket.org/ratfactor/hm-json-browser/

Comme vous pouvez le voir dans la démo, absolument pas de bande de documentation est nécessaire - un seul point d'entrée URI à partir de laquelle toutes les autres ressources et de leurs méthodes HTTP peut être découvert par la navigation.

Par la voie, HAL comme mentionné dans poursuivre la réponse est très, très proche de votre hypothétique exigences pour HATEOAS. C'est un grand standard et il a beaucoup de bonnes idées comme les ressources intégrées, mais il n'a aucun moyen d'informer le client sur tous disponibles HTTP méthodes telles que la SUPPRESSION d'une ressource donnée.

5voto

cayuu Points 1563

Une autre tentative solide (et nouvelle en date de mai 2013) de résolution de HATEOAS pour JSON est disponible ici:

API JSON: http://jsonapi.org/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X