🐷
【Go】 BE制御 ページネーション実装
導入
ページネーションを実装する最も簡単な方法は、すべての一覧データをフロントエンドに返し、ページネーションの制御をフロントエンド側で行う方法です。しかし、この方法では、データ量が膨大になると、初回アクセス時のデータ取得やレンダリングに時間がかかる可能性があります。
この問題を解決する方法としては、ページごとにリクエストを送り、その都度データを取得してレンダリングする方法やSSGを活用して、事前にレンダリングしたデータを提供する方法があります。
今回は、ページごとにリクエストを送る方法について紹介します。
ページネーションの考え方
ページごとにデータを取得するためには、リクエストに以下のパラメータを含める必要があります:
limit:1ページあたりに表示するデータの件数。
offset:取得を開始するデータの位置。
例えば、フロントエンドで1ページに5件のデータを表示する場合、各ページに対応するlimitとoffsetの値は以下のようになります。
ページ番号 | limit | offset | リクエスト例 |
---|---|---|---|
1 | 5 | 0 | GET /api/items?limit=5&offset=0 |
2 | 5 | 5 | GET /api/items?limit=5&offset=5 |
3 | 5 | 10 | GET /api/items?limit=5&offset=10 |
4 | 5 | 15 | GET /api/items?limit=5&offset=15 |
5 | 5 | 20 | GET /api/items?limit=5&offset=20 |
ページネーションの実装
実装はrepogitory層の実装は以下のようになります。ORMはentを使っています。count
はページの最大値をFE側に表示するのに必要です。
func (c *client) AllTodos(ctx context.Context, input *repository.Input) (*repository.TodoGet, error) {
todos, err := c.client.Todo.
Query().
WithLabels().
WithPriority().
WithStatus().
Limit(input.Limit).
Offset(input.Offset).
Order(ent.Desc("created_at")).
All(ctx)
if err != nil {
return nil, err
}
count, err := c.client.Todo.
Query().
Count(ctx)
if err != nil {
return nil, err
}
return &repository.TodoGet{
Todos: todos,
PageCount: count,
}, nil
}
Discussion