what specifically results restful from for enable does apis api rest

specifically - Dividir pelos con REST: ¿una API REST JSON estándar viola HATEOAS?



spring hal (6)

Estuve leyendo sobre REST esta mañana y me encontré con el principio HATEOAS ("hipermedia como el motor del estado de la aplicación") .

Citando la página de REST Wikipedia :

Los clientes realizan transiciones de estado solo a través de acciones que el servidor identifica dinámicamente dentro de hipermedia (por ejemplo, mediante hipervínculos dentro de hipertexto). A excepción de los puntos de entrada fijos simples a la aplicación, un cliente no asume que cualquier acción particular estará disponible para cualquier recurso en particular más allá de los descritos en las representaciones recibidas previamente del servidor.

Y el blog de Roy Fielding :

... si el motor del estado de la aplicación (y, por lo tanto, la API) no está siendo impulsado por el hipertexto, entonces no puede ser RESTful y no puede ser una API REST. Período.

Leí esto como: El cliente solo puede solicitar cambios de estado en función de las acciones disponibles desde el cuerpo de la respuesta del servidor (el hipertexto).

En un mundo HTML, esto tiene perfecto sentido. El cliente solo debería poder solicitar cambios de estado (nuevas acciones / páginas) en función de los enlaces puestos a su disposición a través del hipertexto (HTML).

Cuando el recurso se representa de otras maneras, como JSON, XML, YAML, etc. Esto no es tan evidente.

Tomemos un ejemplo de API REST "JSON":

Creo un nuevo recurso (un nuevo comentario, por ejemplo) enviando una solicitud POST a

/comments.json? # with params...

El servidor responde con:

# 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"}

Sé que ahora puedo acceder a este comentario en el URI que aparece en el encabezado: http://example.com/comments/3.json

Cuando visito http://example.com/comments/3.json veo:

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

Supongamos que la documentación de la API me dice que puedo eliminar este comentario enviando una solicitud DELETE al mismo URI. Esto es bastante común entre las API "REST".

Sin embargo:

La respuesta del servidor en GET http://example.com/comments/3.json no me dice nada acerca de poder eliminar el comentario enviando una solicitud DELETE. Todo lo que me muestra es el recurso.

Que también PUEDO ELIMINAR un comentario con la misma URL es algo que el cliente conoce a través de la información fuera de banda (la documentación) y no es descubierta e impulsada por la respuesta del servidor.

Aquí, el cliente está asumiendo que la acción DELETE (y otras posibles) están disponibles para este recurso y esta información no se ha recibido previamente del servidor.

¿He entendido mal HATEOAS o estoy en lo cierto al decir que una API que coincida con la descripción anterior no sería, en sentido estricto, una API REST?

Soy consciente de que el 100% de adhesión a REST no siempre es posible o la forma más pragmática de hacerlo. He publicado esta pregunta simplemente para satisfacer mi propia curiosidad sobre la teoría detrás de REST, no para obtener consejos sobre las mejores prácticas del mundo real.


JSON como tipo de hipermedia no define un identificador para el flujo de la aplicación. HTML tiene una etiqueta de enlace y forma que guía a un usuario a través de un proceso.

Si su aplicación solo está relacionada con PUT, POST, DELETE, GET en un recurso, su documentación podría explicarlo fácilmente.

Sin embargo, si fuera más complicado agregar una refutación a un comentario y esa refutación fuera un recurso diferente, entonces el comentario necesitaría un tipo de hipermedia que guiara al consumidor a crear la refutación.

Podría usar HTML / XHTML, crear su propio ''bodacious + json'' o usar algo más. Aquí están todos los diferentes tipos de medios http://www.iana.org/assignments/media-types/index.html

Estoy usando HAL y tiene un grupo bastante activo. Aquí hay enlaces a este.

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

http://stateless.co/hal_specification.html

El libro "Creación de API de Hypermedia con HTML5 y nodo" profundiza en hipermedios y tipos de medios. Muestra cómo crear un tipo de medio para un propósito específico o general en XML o JSON.


Jon Moore pronunció una excelente charla en noviembre de 2010 sobre los aspectos prácticos de escribir una API y un cliente verdaderamente RESTful (es decir, con soporte de HATEOAS). En la primera parte, sugiere que JSON no es un tipo de medio adecuado para REST porque carece de una forma común de representar enlaces y métodos HTTP compatibles. Sostiene que el buen XHTML es en realidad perfecto para esto, ya que las herramientas para analizarlo (es decir, XPath) están disponibles, admite formularios (piense en los métodos de creación de plantillas GET y métodos PUT, POST y DELETE) y tiene una forma bien conocida de identificar hipervínculos, además de algunas otras ventajas que se logran principalmente mediante la capacidad de utilizar la API con cualquier navegador web estándar (facilita los trabajos para desarrolladores, control de calidad y personal de soporte).

El argumento que siempre hice antes de ver su charla es que JSON es mucho menos consumidor de ancho de banda que cualquier lenguaje * ML, por ejemplo, XML, HTML, XHTML. Pero al usar XHTML elíptico siempre que sea posible, como enlaces relativos en lugar de absolutos (insinuado pero no tan evidente en el ejemplo que utiliza a lo largo de su charla), y al usar compresión gzip, este argumento pierde mucho peso.

Me doy cuenta de que esfuerzos como JSON-Schema y other RFC están en marcha para intentar estandarizar las cosas en JSON, pero mientras tanto, la charla de Moore me convenció para probar XHTML.


La premisa de su pregunta contiene un aspecto a menudo mal entendido de REST : que la entidad del cuerpo de respuesta de API sea responsable no solo de comunicar el estado representativo del recurso solicitado sino también de comunicar el estado general de la aplicación a la que pertenece el recurso . Estas dos cosas: el estado del recurso y el estado de la aplicación no son lo mismo.

El cuerpo de la entidad de respuesta por definición le proporciona el estado del recurso en un punto en el tiempo. Pero un solo recurso es solo uno de muchos que comprende una aplicación. El estado de la aplicación es el estado combinado de todos los recursos relacionados con el alcance, en cualquier momento, desde la perspectiva del consumidor de la aplicación: humano o máquina. Para entregar este ''estado de aplicación'', una API REST de nivel 3 hace posible HATEOAS.

Dado que el Hipertexto es lo que la mayoría de la gente quiere decir cuando se refiere a los ''Hyper''media en HATEOAS, el poder especial del hipertexto es su capacidad de vincularse a otros medios. Además, dado que la mayoría experimenta hipertexto a través de HTTP / HTML, esto hace que muchos piensen que los hipervínculos solo son posibles a través de una etiqueta de anclaje o etiqueta de enlace dentro del cuerpo de una entidad de respuesta, pero esto no es así.

Si el protocolo de transporte es HTTP, el estado de la aplicación puede y debe comunicarse a través de encabezados. Específicamente, uno o más HEADERS ''Link'' con un atributo ''rel'' para proporcionar semántica. El HEADER de enlace junto con el encabezado ALLOW son los mecanismos HTTP para comunicar cuáles son las próximas transiciones de estado posibles y cómo acceder a ellas.

Si decide no utilizar estos mecanismos incorporados, entonces sus opciones son intentar y comunicar el estado de la aplicación mediante ''piggy-backing'' en su canal de comunicación de estado de recursos, es decir, el cuerpo de respuesta, lo que conduce a tratar de idear alguna forma de especificación adicional en el diseño del recurso en sí.

Cuando se hace esto - ''piggy-backing'' - muchos se topan con problemas de tipo contenido porque el cuerpo de la respuesta tiene que ser especificado por un MIME / tipo de contenido como XML o JSON, lo que significa descubrir cómo implementar los mecanismos de HATEOAS a través de alguna costumbre formato específico de tipo de contenido como etiquetas XML personalizadas o clave: pares de valores de objetos anidados. Puede hacer esto, muchos lo hacen, por ejemplo, consulte la sugerencia de json-api anterior, pero de nuevo HTTP ya proporciona mecanismos para esto.

Creo que nos pasa a nosotros como humanos siempre pensando que tenemos que ver o poder hacer clic en estos enlaces como en el caso de uso web normal, pero estamos hablando de API que solo puedo suponer que se están construyendo no para el consumo humano, sino para consumo de la máquina, ¿verdad? El hecho de que los encabezados (que están allí por cierto como parte de la respuesta) no son visibles en la mayoría de las interfaces humanas para HTTP, es decir, navegadores no es un problema con REST sino más bien una limitación de implementación de los Agentes HTTP en el mercado.

Espero que esto ayude. Por cierto, si quieres un buen navegador humano para las API google ''Paw API Browser''



Una API JSON totalmente reconocible que no requiere ningún conocimiento fuera de banda como lo explicas de manera tan sucinta:

"Que también PUEDO ELIMINAR un comentario con la misma URL es algo que el cliente sabe a través de la información fuera de banda (la documentación) y no es descubierta e impulsada por la respuesta del servidor".

... es completamente posible. Solo requiere un estándar simple y un cliente que entienda el estándar. Consulte hm-json y el proyecto del navegador hm-json:

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

Como puede ver en la demostración, no se necesita absolutamente ninguna documentación fuera de banda, solo un URI de punto de entrada desde el que se pueden descubrir todos los demás recursos y sus métodos HTTP mediante la exploración.

Por cierto, HAL como se menciona en la respuesta de la demanda está muy, muy cerca de sus requisitos hipotéticos para HATEOAS. Es un gran estándar y tiene muchas ideas interesantes, como recursos integrados, pero no tiene manera de informar al cliente sobre todos los métodos HTTP disponibles, como DELETE para un recurso determinado.


Una solución REST podría ser utilizar el Allow-header para informar al cliente de los métodos / acciones disponibles:

> 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 disertación de Fielding establece dos tipos de metadatos: metadatos de representación ; y metadatos de recursos .

El encabezado Permitir en HTTP / 1.1 funciona como metadatos de recursos porque describe alguna propiedad de un recurso; es decir, los métodos que permite.

Al utilizar por completo las características proporcionadas por HTTP, elimina la necesidad de cualquier información fuera de límites y se vuelve más RESTful.

HATEOAS en un contexto HTTP simple describe cómo un cliente puede navegar de una representación a otra siguiendo URI usando GET , mientras que el encabezado Allow informa al cliente de los métodos adicionales admitidos por el recurso que generó la representación.

Es un diseño limpio; el cliente solicitó una representación y, además, recibió un montón de metadatos adicionales sobre el recurso que permiten la solicitud eficiente de otras representaciones.

Creo que la cita que tienes de la página de REST de Wikipedia es algo engañosa en su elección de palabras y no ha ayudado aquí (NB Se ha mejorado desde que se hizo esta pregunta).

Todos los clientes HTTP tienen que suponer que es probable que un método GET esté disponible para la mayoría de los recursos. Lo hacen porque la compatibilidad con GET y HEAD son los requisitos mínimos para un servidor HTTP / 1.1. Sin esta suposición, la web no funcionaría. Si un cliente puede suponer que GET está disponible, ¿por qué no hacer otras suposiciones sobre métodos comunes, como DELETE o POST ?

REST y HTTP apuntan a aprovechar el poder de hacer suposiciones sobre un conjunto básico de métodos para reducir el volumen total de solicitudes en una red; si una solicitud tiene éxito, no hay necesidad de comunicación adicional; pero si una solicitud falla con el estado ''Método 405 no permitido'', entonces el cliente recibe inmediatamente las solicitudes que podrían tener éxito a través del encabezado Permitir:

> 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 el conjunto básico de métodos HTTP / 1.1 no es suficiente, entonces usted es libre de definir el suyo propio. Sin embargo, sería RESTful resolver problemas utilizando las funciones disponibles de HTTP antes de definir nuevos métodos o poner metadatos en el cuerpo del mensaje.