LoginSignup
0
0

More than 1 year has passed since last update.

LaravelをAPIサーバーで利用するときのページネーションの実装(ページあたりの件数、現ページindexの指定方法)

Posted at

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引数は上記の定数で良いと思います。

¥Illuminate¥Database¥Query¥Builder::paginate()を見る感じ
第4引数が存在すれば第3引数$pageNameは参照されてないっぽいです。
未検証ですが第4引数無しにして、現在のインデックスを持つクエリ文字列名を$pageNameに指定すればそれでも動くんじゃないかな

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":[
        // データ。連想配列の配列
    ]
}

参考

https://pgmemo.tokyo/data/archives/1278.html
https://www.slideshare.net/ShoheiOkada/laravel-paginate

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0