Ultimamente ho svolto alcune ricerche approfondite su questa e altre domande relative al paging REST e ho ritenuto costruttivo aggiungere alcune delle mie scoperte qui. Sto espandendo un po 'la domanda per includere le riflessioni sul paging e il conteggio poiché sono intimamente correlati.
intestazioni
I metadati di paging sono inclusi nella risposta sotto forma di intestazioni di risposta. Il grande vantaggio di questo approccio è che lo stesso payload di risposta è solo l'effettivo richiedente dei dati che stava chiedendo. Semplificare l'elaborazione della risposta per i client che non sono interessati alle informazioni di paging.
Esistono un sacco di intestazioni (standard e personalizzate) utilizzate in natura per restituire informazioni relative al paging, incluso il conteggio totale.
X-Total-Count
X-Total-Count: 234
Questo è usato in alcune API che ho trovato in natura. Esistono anche pacchetti NPM per l'aggiunta del supporto per questa intestazione, ad esempio Loopback. Alcuni articoli raccomandano di impostare anche questa intestazione.
Viene spesso utilizzato in combinazione con l' Link
intestazione, che è una soluzione abbastanza buona per il paging, ma manca delle informazioni sul conteggio totale.
collegamento
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Sento, leggendo molto su questo argomento, che il consenso generale è quello di utilizzare l' Link
intestazione per fornire collegamenti di paginazione ai clienti che usano rel=next
, rel=previous
ecc. Il problema è che manca l'informazione di quanti record totali ci sono, che è perché molte API combinano questo con l' X-Total-Count
intestazione.
In alternativa, alcune API, ad esempio lo standard JsonApi , utilizzano il Link
formato, ma aggiungono le informazioni in una busta di risposta anziché in un'intestazione. Ciò semplifica l'accesso ai metadati (e crea un luogo per aggiungere le informazioni sul conteggio totale) a scapito della crescente complessità dell'accesso ai dati effettivi stessi (aggiungendo una busta).
Content-Range
Content-Range: items 0-49/234
Promosso da un articolo di blog chiamato Range header, ti scelgo (per impaginazione)! . L'autore è un valido esempio dell'uso delle intestazioni Range
e Content-Range
per l'impaginazione. Quando leggiamo attentamente la RFC su queste intestazioni, scopriamo che estendere il loro significato oltre intervalli di byte è stato effettivamente anticipato dalla RFC ed è esplicitamente permesso. Se utilizzato nel contesto items
anziché anziché bytes
, l'intestazione Range in realtà ci fornisce un modo sia per richiedere un determinato intervallo di elementi sia per indicare a quale intervallo del risultato totale si riferiscono gli elementi di risposta. Questa intestazione offre anche un ottimo modo per mostrare il conteggio totale. Ed è un vero standard che mappa principalmente uno a uno al paging. È anche usato allo stato brado .
Busta
Molte API, inclusa quella del nostro sito Web di domande e risposte preferito, utilizzano una busta , un involucro attorno ai dati utilizzato per aggiungere meta informazioni sui dati. Inoltre, gli standard OData e JsonApi utilizzano entrambi un inviluppo di risposta.
Il grande svantaggio di questo (imho) è che l'elaborazione dei dati di risposta diventa più complessa poiché i dati reali devono essere trovati da qualche parte nella busta. Inoltre ci sono molti formati diversi per quella busta e devi usare quello giusto. Sta dicendo che le buste di risposta di OData e JsonApi sono molto diverse, con OData che si mescola in metadati in più punti della risposta.
Endpoint separato
Penso che questo sia stato trattato abbastanza nelle altre risposte. Non ho studiato molto perché sono d'accordo con i commenti sul fatto che ciò sia confuso, dato che ora hai più tipi di endpoint. Penso che sia più bello se ogni endpoint rappresenta una (raccolta di) risorse.
Ulteriori pensieri
Non dobbiamo solo comunicare le meta informazioni di paging relative alla risposta, ma anche consentire al cliente di richiedere pagine / intervalli specifici. È interessante esaminare anche questo aspetto per trovare una soluzione coerente. Anche qui possiamo usare le intestazioni (l' Range
intestazione sembra molto adatta) o altri meccanismi come i parametri di query. Alcune persone sostengono di trattare le pagine dei risultati come risorse separate, il che può avere senso in alcuni casi d'uso (ad es /books/231/pages/52
. Ho finito per selezionare una gamma selvaggia di parametri di richiesta di uso frequente come pagesize
, page[size]
ed limit
ecc. Oltre a supportare l' Range
intestazione (e come parametro di richiesta anche).