Paginazione e cursori
01In una frase #sec_4400178a
Tutte le liste dell'API si percorrono con il cursore, mai con il numero di pagina — e il cursore è opaco: la sua forma non è un contratto, il suo uso lo è.
02L'involucro di risposta #sec_95dbbbe4
Ogni punto di chiamata che restituisce una lista restituisce lo stesso involucro: i dati da un lato, la posizione dall'altro.
{
"data": [ ... ],
"page": {
"limit": 100,
"nextCursor": "YzE6NDIx"
}
}
data porta gli elementi. page.limit ricorda la dimensione effettivamente applicata — che non è sempre quella richiesta, vedi più sotto. page.nextCursor porta la posizione da riprendere, o null quando non c'è più nulla dopo.
03Percorrere #sec_6f1e95f9
La prima chiamata non porta un cursore. Ognuna delle successive riprende il nextCursor della precedente.
GET /api/v1/campaigns?limit=100
GET /api/v1/campaigns?limit=100&cursor=YzE6NDIx
GET /api/v1/campaigns?limit=100&cursor=YzE6Mzgy
Il ciclo si ferma su nextCursor: null, non su una pagina incompleta. Una pagina può restituire meno elementi del limite richiesto senza essere l'ultima; fermarsi su questo segnale farebbe perdere il seguito, silenziosamente.
04Il limite #sec_f8bab3ec
Cento elementi di default, cinquecento al massimo. Un valore fuori dai limiti non viene rifiutato: viene riportato entro i limiti, e page.limit dice allora cosa è stato effettivamente applicato.
| Richiesto | Applicato |
|---|---|
| assente | 100 |
| 0 o negativo | 1 |
| 250 | 250 |
| 5000 | 500 |
Ecco perché page.limit figura nella risposta: senza di esso, un cliente che richiede 5000 crederebbe di aver ricevuto tutto.
05Il cursore è opaco #sec_1c8cde92
Il cursore è una stringa. Ciò che codifica è un dettaglio di implementazione che può cambiare senza preavviso, e decodificarlo per fabbricarne un altro è il modo più sicuro per rompere la sua integrazione nella prossima versione.
Due regole sono sufficienti: riprendere quello che la risposta precedente ha dato, tale e quale; non costruirne mai uno.
Un cursore mal formato o manomesso non è un errore: viene trattato come un'assenza di cursore, e il percorso riparte dall'inizio. Un'integrazione che fabbricasse i suoi cursori girerebbe quindi in tondo sulla prima pagina senza che nulla lo segnali.
06L'ordine di percorrenza #sec_3157b042
L'ordine è stabile e decrescente sull'identificatore: gli elementi più recenti per primi. Questo è ciò che rende il percorso sicuro — un elemento aggiunto mentre si effettua la paginazione appare prima della propria posizione, quindi non sposta ciò che rimane da leggere e non lo si vedrà due volte.
La controparte si dice francamente: un percorso lungo non vede ciò che è arrivato dopo la sua prima chiamata. Per recuperare il recente, riavviate un percorso dall'inizio piuttosto che continuare il vecchio.
07Riprendere più tardi #sec_98015cd3
Un cursore rimane utilizzabile oltre la vita del token che lo ha prodotto: rinnovare il token non obbliga a ricominciare il percorso. Conservate la posizione, non la sessione.
08Da ricordare #sec_35ad77bf
Una busta unica per tutte le liste. Un limite tra 1 e 500, riportato nei limiti e ricordato nella risposta. Un cursore che si riprende e che non si fabbrica mai. E una sola condizione di arresto: nextCursor a null.