Últimamente he estado haciendo una investigación exhaustiva sobre esta y otras preguntas relacionadas con la paginación REST y pensé que era constructivo agregar algunos de mis hallazgos aquí. Estoy ampliando la pregunta un poco para incluir pensamientos sobre paginación, así como el recuento, ya que están íntimamente relacionados.
Encabezados
Los metadatos de paginación se incluyen en la respuesta en forma de encabezados de respuesta. El gran beneficio de este enfoque es que la carga útil de respuesta en sí misma es solo el solicitante de datos real que estaba solicitando. Facilitar el procesamiento de la respuesta para los clientes que no están interesados en la información de paginación.
Hay un montón de encabezados (estándar y personalizados) utilizados en la naturaleza para devolver información relacionada con la paginación, incluido el recuento total.
X-Total-Count
X-Total-Count: 234
Esto se usa en algunas API que encontré en la naturaleza. También hay paquetes NPM para agregar soporte para este encabezado, por ejemplo, para Loopback. Algunos artículos recomiendan configurar este encabezado también.
A menudo se usa en combinación con el Link
encabezado, que es una solución bastante buena para la paginación, pero carece de la información de recuento total.
Enlace
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Siento, al leer mucho sobre este tema, que el consenso general es usar el Link
encabezado para proporcionar enlaces de paginación a los clientes que usan rel=next
, rel=previous
etc. El problema con esto es que carece de la información de cuántos registros totales hay, que es por qué muchas API combinan esto con el X-Total-Count
encabezado.
Alternativamente, algunas API y, por ejemplo, el estándar JsonApi , usan el Link
formato, pero agregan la información en un sobre de respuesta en lugar de un encabezado. Esto simplifica el acceso a los metadatos (y crea un lugar para agregar la información del recuento total) a expensas de aumentar la complejidad del acceso a los datos reales (agregando un sobre).
Rango de contenido
Content-Range: items 0-49/234
Promocionado por un artículo de blog llamado encabezado Range, ¡te elijo (para paginación)! . El autor presenta un argumento sólido para usar los encabezados Range
y Content-Range
para la paginación. Cuando leemos cuidadosamente el RFC en estos encabezados, encontramos que extender el significado más allá de los rangos de bytes fue realmente anticipado por el RFC y está explícitamente permitido. Cuando se usa en el contexto de, en items
lugar de bytes
, el encabezado Rango nos da una forma de solicitar un cierto rango de elementos e indicar a qué rango del resultado total se refieren los elementos de respuesta. Este encabezado también ofrece una excelente manera de mostrar el recuento total. Y es un verdadero estándar que se asigna principalmente uno a uno a la paginación. También se usa en la naturaleza .
Sobre
Muchas API, incluida la de nuestro sitio web favorito de preguntas y respuestas, usan un sobre , una envoltura alrededor de los datos que se utiliza para agregar metainformación sobre los datos. Además, OData estándares y JsonApi usan un sobre de respuesta.
La gran desventaja de esto (en mi humilde opinión) es que el procesamiento de los datos de respuesta se vuelve más complejo ya que los datos reales deben encontrarse en algún lugar del sobre. También hay muchos formatos diferentes para ese sobre y debe usar el correcto. Es revelador que los sobres de respuesta de OData y JsonApi son muy diferentes, con OData mezclando metadatos en múltiples puntos de la respuesta.
Punto final separado
Creo que esto se ha cubierto lo suficiente en las otras respuestas. No investigé tanto porque estoy de acuerdo con los comentarios de que esto es confuso ya que ahora tiene múltiples tipos de puntos finales. Creo que es mejor si cada punto final representa una (colección de) recurso (s).
Pensamientos adicionales
No solo tenemos que comunicar la metainformación de paginación relacionada con la respuesta, sino que también le permitimos al cliente solicitar páginas / rangos específicos. Es interesante observar también este aspecto para terminar con una solución coherente. Aquí también podemos usar encabezados (el Range
encabezado parece muy adecuado) u otros mecanismos como los parámetros de consulta. Algunas personas abogan por el tratamiento de las páginas de resultados como recursos separados, que pueden tener sentido en algunos casos de uso (por ejemplo /books/231/pages/52
. Terminé la selección de una gama salvaje de parámetros de la petición uso frecuente, tales como pagesize
, page[size]
y limit
etc, además de apoyar la Range
cabecera (y como parámetro de la petición también).