Pagination
Pagination
Ce document décrit l'utilisation de la pagination implémentée dans les API de Skalin.
# Vue d'ensemble
L'API Skalin utilise la pagination par curseur (keyset pagination) comme méthode principale. Au lieu d'un offset numérique, chaque réponse inclut un token opaque (nextCursor) à passer dans la requête suivante pour obtenir la page suivante.
Info
La pagination par curseur est stateless, efficace sur de grands volumes de données et garantit une cohérence même si des enregistrements sont ajoutés ou supprimés entre deux appels. La pagination par offset (page=) reste disponible mais est déconseillée sur de grands volumes.
# Endpoints supportés
La pagination par curseur est disponible sur les routes suivantes :
| Méthode | Route | Ressource |
|---|---|---|
| GET | /customers | Customers |
| GET | /contacts | Contacts |
| GET | /agreements | Agreements |
| GET | /customers/:customerId/contacts | Contacts |
| GET | /customers/:customerId/agreements | Agreements |
# Paramètres de requête
| size | integer | Nombre de résultats par page. Défaut : 100. Maximum : 500. |
| cursor | string | Token opaque retourné par la page précédente. À omettre pour la première requête. Incompatible avec page. |
| page | integer | Index de page pour la pagination par offset. Défaut : 1. Ignoré si cursor est présent. |
# Structure de la réponse
L'objet metadata.pagination de la réponse contient le curseur vers la page suivante.
Réponse API avec pagination par curseur
{
"status": "success",
"data": ["..."],
"metadata": {
"pagination": {
"size": 100,
"hasNextPage": true,
"nextCursor": "eyJmaWVsZCI6ImNyZWF0ZWRBdCIsImRpciI6ImRlc2MiLCJ0aWVicmVha2VycyI6WyJBY21lIiwiMjAyNC0wMS0xMFQxMjowMDowMFoiLCIxMjMiXX0="
}
}
}
2
3
4
5
6
7
8
9
10
11
hasNextPage: true— il existe une page suivante ; passernextCursordans la prochaine requêtehasNextPage: false— c'est la dernière page ;nextCursorvautnullnextCursorest un token base64url opaque — ne pas l'interpréter ni le conserver entre sessions
# Parcourir les pages
Première page — omettre cursor :
GET /customers?size=50&sort=createdAt.desc
Pages suivantes — passer la valeur nextCursor retournée par la réponse précédente :
GET /customers?size=50&sort=createdAt.desc&cursor=eyJmaWVsZCI6ImNyZWF0ZWRBdCIs...
Répéter jusqu'à ce que hasNextPage soit false.
# Tri
Le paramètre sort contrôle l'ordre des résultats selon le format sort=champ.direction (ex. sort=createdAt.desc). Toujours utiliser la même valeur de sort sur toutes les pages d'un même parcours.
# Customers — /customers
| Champ | Description |
|---|---|
createdAt | Date de création |
updatedAt | Date de dernière mise à jour |
# Contacts — /contacts, /customers/:id/contacts
| Champ | Description |
|---|---|
createdAt | Date de création |
updatedAt | Date de dernière mise à jour |
# Agreements — /agreements, /customers/:id/agreements
| Champ | Description |
|---|---|
mrr | Monthly Recurring Revenue |
arr | Annual Recurring Revenue |
status | Statut du contrat |
startDate | Date de début |
endDate | Date de fin |
engagement | Jours restants avant l'engagement |
notice | Jours restants avant le préavis |
# Pagination par offset
La pagination par offset utilise le paramètre page à la place de cursor. Elle est disponible sur tous les endpoints paginés mais déconseillée sur de grands volumes — les performances se dégradent significativement au-delà de quelques milliers de lignes.
| page | integer | Index de page. Défaut : 1. Ignoré si cursor est présent. |
| size | integer | Nombre de résultats par page. Défaut : 100. Maximum : 500. |
La réponse contient hasNextPage, page et total à la place de nextCursor.
Réponse API avec pagination par offset
{
"status": "success",
"data": ["..."],
"metadata": {
"pagination": {
"size": 50,
"page": 2,
"total": 82,
"hasNextPage": false
}
}
}
2
3
4
5
6
7
8
9
10
11
12
# Valeurs nulles et ordre
Les valeurs nulles sont toujours placées en dernier (NULLS LAST), quelle que soit la direction du tri. L'ordre est déterministe : des tiebreakers internes (nom, date de création, ID) sont appliqués automatiquement lorsque plusieurs enregistrements partagent la même valeur de tri.
# Bonnes pratiques
- Ne pas conserver un curseur entre sessions. Il encode l'état du tri et peut devenir invalide si le schéma évolue.
- Utiliser le même paramètre
sortsur toutes les pages d'un même parcours. - Privilégier la pagination par curseur pour les grands volumes. La pagination par offset (
page=) se dégrade significativement au-delà de quelques milliers de lignes. - Pour exporter tous les enregistrements, boucler jusqu'à ce que
hasNextPage === false.