J'ai fait des recherches approfondies sur cette question et sur d'autres questions relatives à la pagination REST ces derniers temps et j'ai pensé qu'il était constructif d'ajouter certaines de mes conclusions ici. J'élargis un peu la question pour inclure des réflexions sur la pagination ainsi que sur le comptage car ils sont intimement liés.
En-têtes
Les métadonnées de pagination sont incluses dans la réponse sous la forme d'en-têtes de réponse. Le grand avantage de cette approche est que la charge utile de la réponse elle-même n'est que les données réelles demandées par le demandeur. Cela facilite le traitement de la réponse pour les clients qui ne sont pas intéressés par les informations de pagination.
Il existe un certain nombre d'en-têtes (standard et personnalisés) utilisés dans la nature pour renvoyer des informations relatives à la pagination, y compris le décompte total.
X-Total-Count
X-Total-Count: 234
Il est utilisé dans algunos API Je l'ai trouvé dans la nature. Il y a aussi Paquets NPM pour ajouter la prise en charge de cet en-tête à Loopback, par exemple. Quelques articles recommande également de paramétrer cet en-tête.
Il est souvent utilisé en combinaison avec le Link
qui est une bonne solution pour la pagination, mais qui ne contient pas d'informations sur le nombre total.
Lien
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
J'ai l'impression, après avoir lu beaucoup de choses sur ce sujet, que le consensus général est d'utiliser l'outil Link
en-tête pour fournir des liens de radiomessagerie aux clients qui utilisent rel=next
, rel=previous
etc. Le problème est qu'il manque l'information sur le nombre total d'enregistrements, c'est pourquoi de nombreuses API la combinent avec l'option X-Total-Count
l'en-tête.
Par ailleurs, certaines API, par exemple l'API JsonApi utiliser la norme Link
mais en ajoutant les informations dans une enveloppe de réponse plutôt que dans un en-tête. Cela simplifie l'accès aux métadonnées (et crée un endroit où ajouter l'information sur le nombre total) au détriment de la complexité accrue de l'accès aux données elles-mêmes (par l'ajout d'une enveloppe).
Plage de contenu
Content-Range: items 0-49/234
Promu par un article de blog intitulé Range header, je te choisis (pour la pagination) ! . L'auteur présente des arguments solides en faveur de l'utilisation de la Range
y Content-Range
pour la pagination. Lorsque nous lisons attentivement les RFC sur ces en-têtes, nous constatons que l'extension de leur signification au-delà des plages d'octets était en fait prévue par le RFC et est explicitement autorisée. Lorsqu'ils sont utilisés dans le contexte de items
au lieu de bytes
L'en-tête Range nous permet de demander un certain nombre d'éléments et d'indiquer à quelle partie du résultat total les éléments de la réponse se rapportent. Cet en-tête constitue également un excellent moyen d'afficher le nombre total d'éléments. Il s'agit en outre d'une véritable norme qui correspond en grande partie à la pagination. C'est aussi utilisés dans la nature .
Enveloppe
De nombreuses API, y compris celui de notre site de questions-réponses préféré utiliser un enveloppe Les données sont entourées d'une enveloppe qui permet d'ajouter des méta-informations sur les données. Aussi, OData y JsonApi les normes utilisent toutes deux une enveloppe de réponse.
Le gros inconvénient de cette méthode (imho) est que le traitement des données de réponse devient plus complexe car les données réelles doivent être trouvées quelque part dans l'enveloppe. De plus, il existe de nombreux formats différents pour cette enveloppe et vous devez utiliser le bon. Il est révélateur que les enveloppes de réponse d'OData et de JsonApi soient extrêmement différentes, OData mélangeant des métadonnées à plusieurs endroits de la réponse.
Point final séparé
Je pense que cette question a été suffisamment traitée dans les autres réponses. Je n'ai pas approfondi cette question car je suis d'accord avec les commentaires selon lesquels cela prête à confusion car vous avez maintenant plusieurs types de points de terminaison. Je pense qu'il est préférable que chaque point de terminaison représente une (collection de) ressource(s).
Réflexions complémentaires
Nous devons non seulement communiquer les méta-informations relatives à la réponse, mais aussi permettre au client de demander des pages/plages spécifiques. Il est intéressant d'examiner également cet aspect pour aboutir à une solution cohérente. Ici aussi, nous pouvons utiliser des en-têtes (l'en-tête Range
semble très approprié), ou d'autres mécanismes tels que les paramètres de requête. Certains préconisent de traiter les pages de résultats comme des ressources distinctes, ce qui peut avoir du sens dans certains cas d'utilisation (par ex. /books/231/pages/52
. J'ai fini par sélectionner un large éventail de paramètres de requête fréquemment utilisés, tels que pagesize
, page[size]
y limit
etc. en plus de soutenir la Range
(et également comme paramètre de la requête).