Por el libro REST vs Demasiadas solicitudes

8

Del comentario de Roy Fielding sobre su propio artículo denunciando falsas API REST :

Una API verdaderamente RESTful parece hipertexto. Cada unidad de información direccionable lleva una dirección, ya sea explícitamente (p. Ej., Atributos de enlace e identificación) o implícitamente (p. Ej., Derivada de la definición del tipo de medio y la estructura de representación). Los resultados de la consulta se representan mediante una lista de enlaces con información resumida, no mediante matrices de representaciones de objetos (la consulta no sustituye la identificación de recursos).

Esto significa que si necesita, por ejemplo, consultar una lista de los 100 usuarios registrados más recientemente y mostrar sus nombres y correos electrónicos, primero debe hacer una GETconsulta de la lista de resultados, lo que (esencialmente) ser una lista de elementos de enlace, con cada objeto de enlace que contiene el URI de un recurso de usuario. Luego, deberá realizar 100 solicitudes más GET , una para cada recurso de usuario, antes de tener los datos que necesita para mostrar sus resultados.

Eso parece increíblemente ineficiente. ¿Realmente no hay otra forma verdaderamente RESTful de obtener los datos que necesita en 1 o 2 solicitudes?

Jonás
fuente
1
¿No te perdiste la parte: "con información resumida"?
Luc Franken
1
No me lo perdí, pero la "información de resumen" implica "resumen" para mí, no "todos los datos". Específicamente dice "no por conjuntos de representaciones de objetos", que es exactamente lo que necesitamos para nuestra visualización.
Jonás
1
Vemos la lista como un recurso y para nosotros contiene campos como: enlace a un solo recurso, título, descripción breve y # de comentarios, por ejemplo. No incluimos objetos completos porque son demasiado grandes. Por lo tanto, nuestros recursos de la lista proporcionan completamente toda la información necesaria para usarla. Cuando desea más, carga el recurso completo que puede incluir formularios, mucho contenido y otras partes más grandes. Una vez intentamos incluir todos los recursos (proceso de pensamiento de YAGNI) en su totalidad, pero eso se rompió. Entonces agregamos este paso. Y creo que es completamente REST, una lista de información es un recurso en sí misma.
Luc Franken
No intente aplicar estrictamente (a ciegas) las oraciones de Fielding sobre REST. Por supuesto, él es el padre de la arquitectura REST, pero tenga cuidado: la arquitectura REST es para sistemas altamente escalables, por eso se ha inferido de la web. Si tiene sentido usar una matriz de objetos para problemas de rendimiento, entonces hágalo.
AilurusFulgens
HAL + json generalmente se considera RESTful. Incluye una versión reducida (resumen) de los objetos más un enlace al recurso completo.
RubberDuck

Respuestas:

7

¿Realmente no hay otra forma verdaderamente RESTful de obtener los datos que necesita en 1 o 2 solicitudes?

  • Realmente no
  • Pero no lo pienses demasiado

Como de costumbre, cuando piense en REST, tenga en cuenta que existe una implementación de referencia (la red mundial) con la que puede verificar.

Considere el portal de Amazon: cuando abro ese marcador con un caché vacío, veo que mi navegador realiza solicitudes a 275 recursos.

¿Obtendría una mejor latencia si todo ese estado se obtuviera en una sola carga útil? Si.

¿Escalaría? ¿Escalaría en la web? Probablemente no. Eso es 4.5MB de datos que no se pueden compartir porque incluye 1KB que es específico de mi perfil. Si mi colega en el escritorio a mi lado también va a Amazon, ella extrae los mismos datos a través de la red.

Descomponga esa carga útil en recursos direccionables individualmente y, de repente, las cosas mejoran mucho: cada uno de nosotros todavía recibimos nuestro 1KB de personalización, y cada uno todavía tiene nuestra copia en caché local de los 4.5MB, pero no hemos necesitado explotar la red igual de difícil, porque la mayoría de nuestras solicitudes fueron atendidas por un caché compartido local, en lugar de tener que enrutar a través de Internet.

Además, tenga en cuenta que realmente no tiene un problema con múltiples recursos , tiene un problema con múltiples solicitudes . Eso se puede mitigar con HTTP / 2.0 Push Promises , con el servidor empujando proactivamente las representaciones que se pueden almacenar en caché. Quizás: un servidor sin estado no sabe lo que el cliente ha almacenado en caché, y TLS sugiere que el almacenamiento en caché en intermedios no es una prioridad ...

Esto significa que si necesita, por ejemplo, consultar una lista de los 100 usuarios que ingresaron más recientemente y mostrar sus nombres y correos electrónicos, primero debe realizar una consulta GET para obtener la lista de resultados, lo que (esencialmente ) será una lista de elementos de enlace, con cada objeto de enlace que contiene el URI de un recurso de usuario. Debería realizar 100 solicitudes GET más, una para cada recurso de usuario, antes de tener los datos que necesita para mostrar sus resultados.

Por supuesto, si estuviera haciendo esto en html, su representación de los usuarios registrados más recientemente probablemente sería un documento con una lista o una tabla de nombres y direcciones de correo electrónico y enlaces a esos recursos. Ta-da.

No pierdas de vista esta observación de Fielding.

Eso no significa que piense que todos deberían diseñar sus propios sistemas de acuerdo con el estilo arquitectónico REST. REST está destinado a aplicaciones basadas en red de larga duración que abarcan varias organizaciones. Si no ve la necesidad de las restricciones, no las use.

EDITAR

¿Puedo hacer el mismo argumento para una representación JSON? es decir, si el recurso en cuestión es "100 usuarios registrados por última vez" en lugar de los resultados de una consulta parametrizada, ¿puedo devolver los datos en lugar de los enlaces de recursos? Si no, ¿por qué? ¿Por qué JSON es esencialmente diferente de HTML a este respecto?

En qué se parecen: incluir más datos en la "lista de resultados" le ahorra los costos de las solicitudes adicionales, al tiempo que compromete la escala. El tipo de medio específico que está utilizando para la representación no importa, al menos, que yo sepa.

Cómo son diferentes: HTML es un formato hipermedia y JSON no lo es: cualquier implementación de cliente estándar que esté familiarizada con la especificación HTML sabrá cómo encontrar los enlaces en un documento HTML, que admite opciones como la búsqueda previa. JSON no tiene esa estandarización: necesita información fuera de banda sobre la estructura de datos para comprender dónde están los enlaces en una representación JSON. HAL sería una coincidencia más cercana a HTML a este respecto; La principal diferencia entre HAL y HTML es la adopción; HTML tiene una ventaja de 20 años?

Para obtener información adicional, también puede considerar revisar el Formato de sindicación del átomo , que describe tanto las entradas como los feeds (listas de entradas), especialmente las reglas para atom: entry , a las que se puede acceder a través de un recurso independiente o mediante un recurso de fuente.

VoiceOfUnreason
fuente
1
El último párrafo de Fielding debe estar grabado en la frente de todos los pedantes REST en texto inverso, para que puedan verlo cada vez que se miren en el espejo.
Robert Harvey
Gran respuesta como siempre. re: su último párrafo en una representación HTML, ¿puedo hacer el mismo argumento para una representación JSON? es decir, si el recurso en cuestión es "100 usuarios registrados por última vez" en lugar de los resultados de una consulta parametrizada, ¿puedo devolver los datos en lugar de los enlaces de recursos? Si no, ¿por qué? ¿Por qué JSON es esencialmente diferente de HTML a este respecto?
Jonás
@Jonah JSON no es un formato hipermedia, al contrario de HTML (y algunos otros). Un formato hipermedia permite describir enlaces y relaciones. En HTML haces esto con <a href="URI" rel="">y <form method="post">por ejemplo. En JSON no se puede, a menos que lo utilice de manera ad hoc, dado que JSON no define nada de hipermedia (algunos ejemplos de ad-hoc hipermedia uso de JSON: _link : [ ... ], links : [ ... ] , _link_ : [ ... ], etc.) (PD: gran respuesta)
AilurusFulgens
@AilurusFulgens, claro, debería haber sido más específico. Me refería a algo como "hal + json" (o cualquier otro formato hipermedia basado en JSON): el objetivo de la pregunta es el mismo: ¿por qué está bien devolver un "documento" en HTML con todos los datos, pero no hacer lo mismo en un formato hipermedia basado en JSON?
Jonás
Gracias por la edición. así que para asegurarme de que lo entiendo, si devuelve todos los resultados en una tabla HTML, en lugar de decir un <ul>enlace cliqueable, ¿estaría comprometiendo la escala tanto como si hiciera el equivalente en una respuesta hal + json? específicamente, tal respuesta no se escalaría también porque los resultados devueltos, que presumiblemente cambian a menudo, ¿no serán almacenables en caché? mientras que una lista de enlaces contiene menos datos, ¿entonces la parte no almacenable es más pequeña? ¿Es esa la idea o hay algo más que me falta?
Jonás