Paginación en una aplicación web REST
Esta es una reformulación más genérica de esta pregunta. (con la eliminación de las partes específicas de Rails)
No estoy seguro de cómo implementar la paginación en un recurso en una aplicación web RESTful. Suponiendo que tengo un recurso llamadoproducts
, cuál de los siguientes cree que es el mejor enfoque y por qué:
1. Usar solo cadenas de consulta
p.ej.http://application/products?page=2&sort_by=date&sort_how=asc
El problema aquí es que no puedo usar el almacenamiento en caché de página completa y además la URL no es muy limpia y fácil de recordar.
2. Usar páginas como recursos y cadenas de consulta para ordenar
p.ej. http://application/products/page/2?sort_by=date&sort_how=asc
En este caso el problema que se ve es que http://application/products/pages/1
no es un recurso único ya que usarlo sort_by=price
puede dar un resultado totalmente diferente y todavía no puedo usar el almacenamiento en caché de páginas.
3. Usar páginas como recursos y un segmento de URL para ordenar
p.ej. http://application/products/by-date/page/2
Personalmente no veo ningún problema en usar este método, pero alguien me advirtió que no es un buen camino a seguir (no dio una razón, así que si sabes por qué no es recomendado, házmelo saber).
Cualquier sugerencia, opinión, crítica es más que bienvenida. Gracias.
Estoy de acuerdo con Fionn, pero iré un paso más allá y diré que para mí la página no es un recurso, es una propiedad de la solicitud. Eso me hace elegir solo la cadena de consulta de la opción 1. Simplemente se siente bien. Me gusta mucho cómo está estructurada la API de Twitter . Ni demasiado simple ni demasiado complicado, bien documentado. Para bien o para mal, es mi diseño preferido cuando no estoy seguro de hacer algo de una forma u otra.
Creo que el problema con la versión 3 es más un problema de "punto de vista": ¿ve la página como el recurso o los productos en la página?
Si ve la página como el recurso, es una solución perfectamente buena, ya que la consulta de la página 2 siempre arrojará la página 2.
Pero si ve los productos en la página como el recurso, tiene el problema de que los productos en la página 2 pueden cambiar (productos antiguos eliminados o lo que sea), en este caso el URI no siempre devuelve los mismos recursos.
Por ejemplo, un cliente almacena un enlace a la página de lista de productos X; la próxima vez que se abra el enlace, es posible que el producto en cuestión ya no esté en la página X.
HTTP tiene un excelente encabezado Range que también es adecuado para paginación. puedes enviar
Range: pages=1
tener sólo la primera página. Eso puede obligarte a repensar qué es una página. Quizás el cliente quiera una gama diferente de artículos. El encabezado de rango también funciona para declarar un pedido:
Range: products-by-date=2009_03_27-
para obtener todos los productos más nuevos que esa fecha o
Range: products-by-date=0-2009_11_30
para obtener todos los productos anteriores a esa fecha. Probablemente '0' no sea la mejor solución, pero RFC parece querer algo para iniciar el rango. Es posible que se hayan implementado analizadores HTTP que no analicen unidades = -range_end.
Si los encabezados no son una opción (aceptable), creo que la primera solución (todo en una cadena de consulta) es una forma de manejar las páginas. Pero, por favor, normalice las cadenas de consulta (ordene los pares (clave = valor) en orden alfabético). Esto resuelve el problema de diferenciación "?a=1&b=x" y "?b=x&a=1".
La opción 1 parece la mejor, en la medida en que su aplicación considera la paginación como una técnica para producir una vista diferente del mismo recurso.
Dicho esto, el esquema de URL es relativamente insignificante. Si está diseñando su aplicación para que esté basada en hipertexto (como todas las aplicaciones REST deben serlo por definición), entonces su cliente no construirá ningún URI por sí solo. En cambio, su aplicación le dará los enlaces al cliente y el cliente los seguirá.
Un tipo de enlace que su cliente puede proporcionar es un enlace de paginación.
El agradable efecto secundario de todo esto es que incluso si cambia de opinión sobre la estructura del URI de paginación e implementa algo totalmente diferente la próxima semana, sus clientes pueden continuar trabajando sin ningún tipo de modificación.
Siempre he usado el estilo de la opción 1. El almacenamiento en caché no ha sido una preocupación ya que, de todos modos, los datos cambian con frecuencia en mi caso. Si permite que el tamaño de la página sea configurable, los datos no se podrán almacenar en caché.
No encuentro la URL difícil de recordar ni sucia. Para mí, este es un buen uso de los parámetros de consulta. El recurso es claramente una lista de productos y los parámetros de consulta solo indican cómo desea que se muestre la lista: ordenada y en qué página.