Una gran cantidad de lo que pensé que sabía sobre REST aparentemente está mal, y no estoy solo. Esta pregunta tiene una larga introducción, pero parece necesaria porque la información está un poco dispersa. La pregunta real viene al final si ya está familiarizado con este tema.
Desde el primer párrafo de las API REST de Roy Fielding deben estar impulsadas por hipertexto , está bastante claro que él cree que su trabajo está siendo ampliamente malinterpretado:
Me frustra la cantidad de personas que llaman a cualquier interfaz basada en HTTP una API REST. El ejemplo de hoy es la API REST de SocialSite . Eso es RPC. Grita RPC. Hay tanto acoplamiento en exhibición que debería recibir una calificación X.
Fielding continúa enumerando varios atributos de una API REST. Algunos de ellos parecen ir en contra de la práctica común y los consejos comunes en SO y otros foros. Por ejemplo:
Se debe ingresar una API REST sin conocimiento previo más allá del URI inicial (marcador) y un conjunto de tipos de medios estandarizados que son apropiados para la audiencia prevista (es decir, se espera que los comprenda cualquier cliente que pueda usar la API). ...
Una API REST no debe definir jerarquías o nombres de recursos fijos (un acoplamiento obvio de cliente y servidor). ...
Una API REST debería dedicar casi todo su esfuerzo descriptivo a definir los tipos de medios utilizados para representar recursos y controlar el estado de la aplicación, o definir nombres de relaciones extendidas y / o marcas habilitadas para hipertexto para tipos de medios estándar existentes. ...
La idea de "hipertexto" juega un papel central, mucho más que la estructura URI o lo que significan los verbos HTTP. "Hipertexto" se define en uno de los comentarios:
Cuando yo [Fielding] digo hipertexto, me refiero a la presentación simultánea de información y controles de manera que la información se convierte en la posibilidad a través de la cual el usuario (o autómata) obtiene opciones y selecciona acciones. Hypermedia es solo una expansión de lo que significa el texto para incluir anclajes temporales dentro de un flujo de medios; la mayoría de los investigadores han abandonado la distinción.
El hipertexto no necesita ser HTML en un navegador. Las máquinas pueden seguir enlaces cuando comprenden el formato de datos y los tipos de relaciones.
Supongo que en este punto, pero los dos primeros puntos anteriores parecen sugerir que la documentación de API para un recurso de Foo que se parece a lo siguiente conduce a un acoplamiento estrecho entre el cliente y el servidor y no tiene lugar en un sistema RESTful.
GET /foos/{id} # read a Foo
POST /foos/{id} # create a Foo
PUT /foos/{id} # update a Foo
En cambio, un agente debería verse obligado a descubrir los URI de todos los Foos, por ejemplo, emitiendo una solicitud GET contra / foos. (Esos URI pueden seguir el patrón anterior, pero eso no viene al caso). La respuesta utiliza un tipo de medio que es capaz de transmitir cómo acceder a cada elemento y qué se puede hacer con él, dando lugar al tercer punto anterior. . Por este motivo, la documentación de la API debe centrarse en explicar cómo interpretar el hipertexto contenido en la respuesta.
Además, cada vez que se solicita un URI a un recurso de Foo, la respuesta contiene toda la información necesaria para que un agente descubra cómo proceder, por ejemplo, accediendo a los recursos asociados y principales a través de sus URI, o tomando medidas después de la creación. / eliminación de un recurso.
La clave de todo el sistema es que la respuesta consiste en hipertexto contenido en un tipo de medio que transmite a sí mismo al agente opciones para continuar. No es diferente a la forma en que funciona un navegador para los humanos.
Pero esta es mi mejor suposición en este momento en particular.
Fielding publicó un seguimiento en el que respondió a las críticas de que su discusión era demasiado abstracta, carente de ejemplos y rica en jerga:
Otros intentarán descifrar lo que he escrito de maneras que sean más directas o aplicables a alguna preocupación práctica de hoy. Probablemente no lo haga, porque estoy demasiado ocupado lidiando con el próximo tema, preparándome para una conferencia, escribiendo otro estándar, viajando a algún lugar distante o simplemente haciendo las pequeñas cosas que me hacen sentir que me he ganado mi sueldo.
Entonces, dos preguntas simples para los expertos en REST con una mentalidad práctica: ¿cómo interpretas lo que dice Fielding y cómo lo pones en práctica al documentar / implementar API REST?
Editar: esta pregunta es un ejemplo de lo difícil que puede ser aprender algo si no tienes un nombre para lo que estás hablando. El nombre en este caso es "Hypermedia como motor del estado de la aplicación" (HATEOAS).
Respuestas:
Creo que tu explicación lo cubre principalmente. Los URI son identificadores opacos que, en su mayor parte, no deben comunicarse más allá del URI de marcador que utiliza el agente de usuario para acceder a la aplicación.
En cuanto a la documentación, esta pregunta se ha hecho varias veces. Documenta su tipo de medio, junto con los controles de hipervínculo que contiene (enlaces y formularios), y el modelo de interacción si así lo desea (ver AtomPub).
Si documenta los URI o cómo crearlos, lo está haciendo mal.
fuente
Tu interpretación me parece correcta. Creo que las limitaciones de Fielding se pueden aplicar de forma práctica.
Realmente me gustaría ver a alguien publicar algunos buenos ejemplos de cómo documentar una interfaz REST. Hay tantos ejemplos deficientes, tener algunos válidos para señalar a los usuarios sería muy valioso.
fuente
application/json
y que el modelo de recursos son realmente las relaciones. ¿Entendí mal este aspecto de REST? También he leído una de sus respuestas SO que parece señalar que esos contratos de "un atributo" deben evitarse ...He estado buscando un buen ejemplo de una API escrita siguiendo las HATEOAS y tuve problemas para encontrar una (encontré que tanto la API de SunCloud como AtomPub eran difíciles de aplicar a una situación de API "normal"). Así que intenté hacer un ejemplo realista en mi blog que siguiera los consejos de Roy Fieldings sobre lo que significa ser una implementación REST adecuada. Me resultó muy difícil dar con el ejemplo, a pesar de que, en principio, es bastante simple (simplemente confuso cuando se trabaja con una API en lugar de una página web). Entiendo con lo que Roy estaba teniendo problemas y estoy de acuerdo, es solo un cambio en la mentalidad para implementarlo correctamente para una API.
Eche un vistazo: Ejemplo de API usando Rest
fuente
La única excepción a dar instrucciones sobre cómo construir URI es que está permitido enviar una plantilla de URI en la respuesta de hipertexto, con campos que el cliente debe sustituir automáticamente, utilizando otros campos en el hipertexto. Sin embargo, esto generalmente no termina ahorrando mucho ancho de banda, ya que la compresión gzip manejará las partes repetidas de los URI lo suficientemente bien como para no molestarse con esto.
Algunas buenas discusiones sobre REST y los HATEOAS relacionados:
Ventajas de (también) usar HATEOAS en API RESTFul
Cómo tomar una taza de café
fuente
Para los interesados, encontré un ejemplo detallado de HATEOAS en la práctica en Sun Cloud API .
fuente
Lo que la mayoría de la gente se equivoca es que (al menos eso creo) en el mundo REST no documenta su "interfaz de descanso", lo que documenta es un tipo de medio, independientemente de su servidor o servicio.
fuente
Creo que a lo largo de la cantidad de años que REST ha estado ahí, los tecnólogos han llegado a un acuerdo con el concepto de un recurso y lo que realmente es o no es REST.
De acuerdo con el Modelo de Madurez de Richardson, hay 4 niveles (0-3) que definen cuán RESTful es su API, con 3 significando una API RESTful, tal como Roy Fielding pretendía que fuera.
El nivel 0 es cuando tiene un URI de punto de entrada, como SOAP.
El nivel 1 significa que la API es capaz de distinguir entre diferentes recursos y tiene más de un punto de entrada; todavía huele a SOAP.
El nivel 2 es cuando usa verbos HTTP: GET, POST, DELETE principalmente. Este es el nivel en el que REST realmente entra en escena.
En el nivel 3, comienza a usar controles hipermedia para hacer que su API sea realmente RESTful.
Enlaces sugeridos para lectura adicional:
fuente
Absolutamente correcto. Me gustaría señalar además que las plantillas de URI están perfectamente bien dentro de una aplicación RESTful siempre que los patrones sean de documentos recibidos del servidor (OpenSearch es un ejemplo adecuado). En el caso de las plantillas de URI, usted documenta dónde se utilizan y cuáles son los marcadores de posición esperados en la plantilla, pero no las plantillas en sí. Algo contrario a lo que dijo Wahnfrieden, esto no es una excepción.
Por ejemplo, en mi trabajo tenemos un sistema de administración de dominio interno y el documento de servicio especifica dos plantillas de URI: una para producir una URI de mejor estimación para un recurso de dominio y otra para construir una URI para consultar la disponibilidad del dominio. Todavía es posible hojear la colección de dominios para averiguar cuál es el URI de un dominio dado, pero dada la inmensa cantidad de dominios que administra, esto no sería factible para el cliente, por lo que les da una forma de adivinar cuál es el El URI de un recurso de dominio podría ser una gran ventaja en términos de facilidad de implementación desde la perspectiva del cliente y ancho de banda desde el servidor.
Continúe con su pregunta: nuestra documentación normativa son los recursos expuestos, el efecto de varios métodos en esos recursos y los tipos de medios de representación utilizados y sus esquemas, y a qué tipo de recursos apuntan las URI en esas representaciones.
También incluimos documentación no normativa (informativa) que ha adjuntado un descargo de responsabilidad para no leer demasiado en los URI mencionados en el documento, que brinda ejemplos de interacciones típicas cliente-servidor. Esto pone la documentación normativa bastante abstracta en términos concretos.
fuente
Supongamos que
GET /foos/createForm
se invoca para obtener valores de campos de formulario para los que se deben proporcionar cuando vayamos a crearPOST /foos
. Ahora, esta URL en particular, es decir, la 1 utilizada para crear foos, debe mencionarse en la respuestaGET /foos/createForm
como un enlace de acción de envío de acuerdo con la propuesta de Fielding, ¿verdad?Entonces, ¿cuál es el beneficio de mapear acciones a verbos Http conocidos a acciones? Se anula la "convención sobre código / configuración".
fuente