📖
LaravelをAPIサーバーで利用するときのページネーションの実装「ページあたりの件数」「現ページindex」を指定してページネーション
Nuxt/Laravel、SSRでの業務システムの開発に携わっているのですが、LaravelをAPIサーバとして使うときの実装でややハマったのでメモ。
pagenate()メソッドの仕様
クエリビルダ or Eloquentクエリでのpagenate()メソッドですが、今までの案件で見てきたソースの記述だと
User::where('id', '>', '100')->paginate(15); //1ページあたり15件づつ取得する
このような数値型の引数が1つだけ渡され「1ページあたりの数」のみを指定している実装しか見たことがなかったのですがページネーションって、「1ページあたりの数」と「現在のページインデックス」の2つの値が必要じゃない??と疑問に思ったところなんと、pagenate()は自動でGETリクエストのパラメータpage
の値を現在のページ番号として参照しているのでした。
フロントに.blade利用しているときはlinks()を利用すれば上記の仕様に合わせてページリンクを出力するというブラックボックス化されています。
但し、対応してるのはGETのみであり、POSTにpageパラメータで数値渡しても機能してくれませんでした。
(取得系のエンドポイントまでも全てPOSTでルーティングされてる変な設計の案件でこの壁にぶつかった。)
「1ページあたりの件数」「現ページインデックス」を指定してページネーションを実装する方法
HTTPメソッドにPOST使いたい時orパラメータ名にpage
以外を使いたいときは「1ページあたりの数」と「現在のページ数」を明示的に引数に渡します。
User::paginate(
$perPage, // 1ページあたりの件数
['*'],
'page',
$currentPage // 現在のページインデックス値
);
第2,3引数は上記の定数で良いと思います。
APIが返すJSONデータ
paginate()はLengthAwarePaginator型を返し、データは下記の構造になります。jsonで返され、フロント側でもこのオブジェクトを扱うことになります。
{
"total":13, // 全ページのアイテム総数
"per_page":3, // 1ページあたりの件数
"current_page":1, // 現ページのインデックス
"last_page":5, // 最終ページのインデックス
"next_page_url":"http:\/\/localhost:8000\/list?page=2", // 次のページのURLフルパス
"prev_page_url":null, // 前のページのURLフルパス
"from":1, // ページ内1要素目のアイテムインデックス(○~○件/全○件中)の表示に使える
"to":3, // ページ内最後の要素のアイテムのインデックス(○~○件/全○件中)の表示に使える
"data":[
// データ。連想配列の配列
]
}
参考
Discussion