Un’API che restituisce elenchi deve limitare il numero di elementi inviati in ogni risposta. Senza paginazione, una richiesta può consumare risorse inutilmente, aumentare la latenza e risultare difficile da gestire per chi integra il servizio. La scelta non riguarda soltanto la sintassi: il meccanismo incide sugli elementi visibili quando i dati cambiano, sulle modalità di navigazione e sulle garanzie offerte.
Le due opzioni più comuni sono la paginazione con offset, che indica quanti record saltare, e quella con cursore, che usa un riferimento per riprendere da una posizione. La scelta dipende dalle modalità d’uso e dalle garanzie necessarie, non dall’esistenza di una strategia migliore in assoluto.
Che cosa deve garantire una risposta paginata

Prima di scegliere il meccanismo, definisci il contratto della raccolta. Decidi almeno la dimensione massima della pagina, l’ordinamento degli elementi, come richiedere la pagina successiva e cosa accade quando non ci sono altri risultati. Specifica anche come si combinano paginazione, filtri e ordinamento.
L’ordinamento deve essere deterministico. Per esempio, ordinare solo per data può lasciare più record a pari merito. Se non è definito come risolvere le parità, richieste diverse possono restituire gli elementi in posizioni differenti. Aggiungere un criterio univoco, come l’identificativo del record, consente di stabilire una sequenza precisa.
Una risposta utile può includere gli elementi e un riferimento per continuare, oltre a metadati come la dimensione effettiva della pagina. Non tutti i client hanno bisogno del numero totale dei risultati: calcolarlo può avere un costo e, nelle raccolte che cambiano spesso, il totale può diventare rapidamente obsoleto. Includi solo le informazioni necessarie al caso d’uso.
Paginazione con offset: semplice per raggiungere una posizione
Con l’offset, il client richiede un limite e il numero di elementi da saltare. Una richiesta, in termini concettuali, potrebbe essere: «restituisci 20 elementi a partire dal record 40». È un modello facile da spiegare, adatto alle interfacce con pagine numerate, salti a una pagina specifica o accesso diretto a risultati più avanti nell’elenco.
Il vantaggio principale è la semplicità del contratto. I client possono creare collegamenti alle pagine e i team possono ragionare per intervalli. Può essere sufficiente anche per raccolte piccole o relativamente stabili, soprattutto quando la navigazione diretta è un requisito concreto.
Il limite emerge quando i dati cambiano tra una richiesta e l’altra. Se il client carica la prima pagina e, prima di chiedere la successiva, viene inserito un elemento all’inizio dell’ordinamento, l’offset successivo può includere di nuovo un record già visto. Se invece viene eliminato un elemento prima della posizione richiesta, un record non ancora restituito può essere saltato. L’offset, da solo, non garantisce una vista coerente di una raccolta dinamica.
Inoltre, raggiungere posizioni molto avanzate può richiedere di esaminare o scartare molti record, a seconda del database, della query e degli indici. Non è una regola uguale per tutti i sistemi: misura il comportamento con query rappresentative. Se le pagine profonde diventano lente, limita i salti oppure valuta un altro meccanismo.
Paginazione con cursore: continuare da una posizione
Con la paginazione tramite cursore, la risposta fornisce un riferimento che il client invia per ottenere il gruppo successivo di risultati. Il cursore rappresenta una posizione all’interno di un ordinamento; può basarsi, per esempio, sul valore di ordinamento e su un identificativo che risolve le parità. Il client non deve conoscere la struttura interna del riferimento.
Per un funzionamento prevedibile, la query deve mantenere lo stesso ordinamento tra le richieste. Un cursore basato su una data richiede un criterio aggiuntivo se più righe hanno la stessa data. Le modifiche concorrenti possono ancora influire sui risultati delle pagine successive, ma una strategia basata sulla posizione nell’ordinamento tende a evitare gli spostamenti causati dal salto di un certo numero di righe. Questo non equivale necessariamente a uno snapshot immutabile: tale garanzia richiede un comportamento aggiuntivo, da progettare e documentare.
Il cursore dovrebbe essere opaco per il consumatore. Può codificare dati sulla posizione, ma codificare non significa cifrare né proteggere. Non inserire informazioni sensibili senza una protezione adeguata e verifica che il cursore sia valido per la query, l’utente e il relativo contesto di autorizzazione. Definisci anche se scade e quale risposta riceve il client quando non è più utilizzabile.
Questa soluzione è adatta a percorsi sequenziali, feed, cataloghi ampi e processi che avanzano tra i risultati senza saltare a una pagina arbitraria. Rende però più complessa la navigazione diretta e richiede attenzione al formato, alla validazione e alla compatibilità dei cursori.
Criteri pratici per scegliere
Valuta l’esperienza richiesta dal consumatore e le caratteristiche della raccolta. In sintesi:
- Scegli l’offset se sono importanti le pagine numerate o i salti diretti, la raccolta è limitata oppure le modifiche durante la navigazione hanno un impatto accettabile.
- Scegli il cursore per consultazioni sequenziali, raccolte potenzialmente molto ampie o quando inserimenti ed eliminazioni rendono indesiderabili gli spostamenti tra le pagine.
- Confronta i costi reali con query e dimensioni rappresentative: strategia, indici, filtri e database incidono sulle prestazioni.
- Considera l’integrazione: un’esportazione in blocco può dover avanzare in modo affidabile; un’interfaccia di amministrazione potrebbe invece richiedere il salto a una pagina precisa.
Non mescolare i due modelli senza chiarirne l’ambito. Usare l’offset per alcune query e il cursore per altre può avere senso, ma il contratto di ogni raccolta deve essere documentato con chiarezza. Non presentare inoltre il cursore come garanzia di coerenza totale se il progetto conserva solo una posizione e la raccolta continua a cambiare.
Filtri, ordinamento e limiti: il contratto completo
Il cursore e la richiesta della pagina successiva devono corrispondere agli stessi filtri e allo stesso ordinamento della risposta iniziale. Se il client modifica questi parametri, deve avviare un nuovo percorso anziché riutilizzare un riferimento relativo a un’altra query. L’API può rifiutare la combinazione oppure emettere cursori che includono il contesto necessario per convalidarla.
Documenta una dimensione predefinita e un massimo per richiesta. Un limite evita risposte eccessive, ma deve essere coerente con il consumo previsto e non costringere il client a effettuare troppe chiamate. Specifica cosa accade se i valori sono assenti, non validi o superiori al massimo: applicare un limite e restituire un errore sono entrambe possibilità; l’importante è mantenere un comportamento coerente.
Anche l’ordinamento richiesto dall’utente necessita di regole chiare. Accetta solo campi e direzioni consentiti, stabilisci un criterio deterministico per risolvere le parità ed evita di combinare per errore un nuovo ordinamento con un cursore precedente. Questi dettagli riducono ripetizioni, omissioni e query difficili da ottimizzare.
Migrare senza interrompere i client esistenti
Se un’API espone già l’offset, modificare la risposta o rimuovere parametri può interrompere applicazioni e integrazioni. Prima della migrazione, individua i client, le modalità d’uso, le pagine profonde e gli errori osservati. Se la telemetria non è sufficiente, registra le richieste per capire quali parametri vengono usati, nel rispetto delle politiche applicabili in materia di privacy e conservazione.
- Definisci il nuovo contratto: ordinamento, filtri, dimensione massima, formato opaco del cursore e comportamento in caso di cursori non validi.
- Introduci la compatibilità in modo esplicito: per esempio, con una nuova route o un nuovo parametro, oppure con una transizione documentata che mantenga temporaneamente il meccanismo precedente.
- Verifica le modifiche concorrenti, le parità nell’ordinamento, l’ultima pagina, i filtri modificati e i cursori malformati o riutilizzati fuori contesto.
- Monitora adozione e prestazioni prima di ritirare la vecchia opzione. Comunica i cambiamenti e fornisci ai consumatori istruzioni per l’aggiornamento.
Evita che la risposta cambi silenziosamente significato a seconda del client o che il server interpreti in due modi un parametro ambiguo. La compatibilità deve poter essere verificata; date e condizioni di ritiro devono essere documentate, non date per scontate.
Lista di controllo per la decisione

- I consumatori devono poter passare direttamente a una pagina numerata?
- I dati cambiano durante la consultazione e quale effetto hanno ripetizioni o omissioni?
- L’ordinamento è deterministico e include un criterio univoco per risolvere le parità?
- Sono state misurate query profonde e dimensioni di pagina realistiche?
- Sono definiti filtri, limiti, errori e riutilizzo dei cursori?
- Esiste una strategia di compatibilità e un modo per monitorare l’adozione?
Se la navigazione diretta è fondamentale e la raccolta è gestibile, l’offset può essere una scelta ragionevole. Se prevale la consultazione sequenziale e il volume o le modifiche rendono fragili gli spostamenti tra pagine, il cursore è spesso più adatto. Definisci prima le garanzie necessarie e scegli poi il meccanismo: così l’API risponde alle reali esigenze dei consumatori e può evolvere senza sorprese.
