J’ai récemment travaillé sur l’API groups et j’ai quelques réflexions à propos de la pagination, en particulier dans le contexte non-découverte.
Le contexte
Pour plus de clarté, par « contexte de découverte », j’entends la pagination dans list_controller.rb et tags_controller.rb, qui utilisent des méthodes similaires construct_url_with pour générer les URLs des pages précédente et suivante.
À ce sujet, ces méthodes construct_url_with pourraient peut-être être regroupées dans un module inclus, étant donné leur grande similarité. Cependant, cette pagination est assez intégrée à la génération des listes de sujets, ce qui en fait une catégorie à part.
Le modèle
Dans le contexte non-découverte, la pagination utilise une version de ceci :
page = params[:page].to_i
page_size = 38
items = items.offset(page * page_size).limit(page_size)
Vous pouvez voir une version de ce modèle dans divers contrôleurs, par exemple (liste non exhaustive) :
- groupes
- web hooks
- e-mails
- notifications
- éléments du répertoire
- journaux d’actions du personnel
…
Il y a quelques problèmes avec la pagination lors de l’utilisation de ces points de terminaison depuis un client tiers.
Les problèmes
Spécifique : inclusion de l’URL « load more »
Certains de ces points de terminaison renvoient une URL « load more » (avec la page suivante), même s’il n’y a plus de pages.
Par exemple, il y a 9 groupes visibles (pour moi) sur meta. Cependant, l’entrée load_more_groups avec une deuxième page inexistante (la page « 1 » est la deuxième page, car la numérotation des pages commence en réalité à 0) apparaît dans le fichier .json de cette page :
https://meta.discourse.org/g.json
...
"total_rows_groups":9,
"load_more_groups":"/groups?page=1"
Cela pourrait être décrit comme un « bug » de ce point de terminaison, car un client API cherche souvent à utiliser une URL « load more » lors de l’itération sur les pages, plutôt que de gérer lui-même le comptage des pages.
Général : nomenclature différente, gestion de la taille des pages et données de pagination renvoyées
Plus généralement, il existe une grande variabilité dans la nomenclature de la pagination, les tailles de pages et les données de pagination renvoyées dans les contextes non-découverte. Par exemple :
- « page » est appelée soit
:pagesoit:offset. - « nombre total d’éléments » est parfois inclus sous la forme
total_rows_*, mais il n’est pas toujours présent et est parfois nommé différemment. - la plupart des tailles de pages sont assignées à des variables localement dans leurs actions respectives et varient quelque peu, ce qui signifie qu’il faut chercher pour les trouver.
Suggestion
Maintenant, il y a diverses raisons pour plusieurs des points que j’ai soulevés. De nombreux points de terminaison non-découverte sont principalement (ou uniquement) consommés par le client de l’application Discourse et sont adaptés à ce client. Cela a du sens.
Cela dit, il pourrait y avoir une démarche qui commence à déplacer progressivement la pagination non-découverte, en particulier pour les points de terminaison souvent consommés par des clients externes (comme les groupes), vers une plus grande standardisation, ce qui faciliterait également la résolution de problèmes tels que l’inclusion de l’URL « load more ».
Essentiellement, j’envisage un module « Pagination » qui codifie le modèle et pourrait gérer la pagination dans certains points de terminaison sélectionnés, peut-être en commençant par les groupes.
Je pourrais éventuellement proposer une PR à ce sujet, mais j’ai pensé en parler d’abord pour en discuter.