最近、groups API を使って作業をしており、特にディスカバリーコンテキスト以外のページネーションについていくつか考えがあります。
コンテキスト
明確にするために、「ディスカバリーコンテキスト」とは、list_controller.rb や tags_controller.rb におけるページネーションを指します。これらは、前ページと次ページの URL を生成するために、同様の construct_url_with メソッドを使用しています。
この点について、これらの construct_url_with メソッドは非常に似ているため、インクルードするモジュールに統合できるかもしれません。ただし、このページネーションはトピックリストの生成に不可欠なため、別のカテゴリとして扱われています。
パターン
ディスカバリーコンテキスト以外では、ページネーションは以下のようなパターンのいずれかを使用しています。
page = params[:page].to_i
page_size = 38
items = items.offset(page * page_size).limit(page_size)
このパターンのバリエーションは、さまざまなコントローラーで見ることができます(以下は網羅的ではありません)。
- groups
- web hooks
- emails
- notifications
- directory items
- staff action logs
…
サードパーティのクライアントからこれらのエンドポイントを使用する場合、ページネーションにはいくつかの問題があります。
問題点
特定の問題:「もっと読み込む」URL の含め方
これらのエンドポイントの一部は、さらにページがない場合でも「もっと読み込む」URL(次のページ)を返すことがあります。
例えば、meta には私にとって 9 つのグループが表示されています。しかし、そのページの .json には、存在しない 2 ページ目(ページ番号は実質的に 0 から始まるため、ページ「1」が 2 ページ目)を持つ load_more_groups エントリが含まれます。
https://meta.discourse.org/g.json
...
"total_rows_groups":9,
"load_more_groups":"/groups?page=1"
これはエンドポイントの「バグ」と表現できるかもしれません。API クライアントは、ページ数を自分で処理するのではなく、ページを反復する際に「もっと読み込む」URL を使用しようとする傾向があるためです。
一般的な問題:用語、ページサイズの扱い、返されるページネーションデータの不一致
より一般的に、ディスカバリーコンテキスト以外では、ページネーションの用語、ページサイズ、返されるページネーションデータにかなりのばらつきがあります。例えば、
- 「ページ」は
:pageまたは:offsetと呼ばれます。 - 「アイテムの総数」は
total_rows_*として含まれることもありますが、常に含まれるわけではなく、別の名称で呼ばれることもあります。 - ほとんどのページサイズは、関連するアクション内でローカル変数に割り当てられており、多少異なります。そのため、それらを探すために掘り下げる必要があります。
提案
さて、私が指摘したことの多くには、さまざまな理由があります。ディスカバリーコンテキスト以外の多くのエンドポイントは、主に(あるいは唯一)Discourse アプリクライアントによって消費されており、そのクライアントに合わせて調整されています。これは理にかなっています。
とはいえ、外部クライアントでよく消費されるエンドポイント(例えば groups など)を中心に、ディスカバリーコンテキスト以外のページネーションを徐々に標準化に向けて進める動きがあってもよいかもしれません。これにより、「もっと読み込む」URL の含め方といった問題に対処しやすくなるでしょう。
私が考えているのは、パターンを明確にし、選択されたエンドポイント(おそらく groups から開始)でページネーションを処理できる「Pagination」モジュールです。
これに関する PR を作成することも可能ですが、まずは議論のために提起しました。