LoginSignup
6

More than 3 years have passed since last update.

posted at

updated at

Laravel 5.7 + GraphQL(Pagination編)

今回はLaravel5.7とGraphQLを使ってページネーションを実装します。

シリーズ記事

Laravel 5.7 ページネーション

$users = DB::table('users')->paginate(15);
$users = App\User::paginate(15);

Laravelではいくつページネーションする方法がありますが、
一番簡単な方法はQueryBuilderやEloquentBuilderから paginate メソッドを使う方法です。

Laravel 5.7 + GraphQL + paginate

GraphQLにて実装します。
前回までのソースコードからの詳細な差分はコミットを参照ください。
https://github.com/ucan-lab/practice-laravel-graphql/commit/cbbe5a812e01bdfde155f12286e24115ec40649e

app/GraphQL/Query/PostsQuery.php

PostsQueryをページネーションに対応します。

    public function type() : PaginationType
    {
        return GraphQL::pagination(GraphQL::type('PostType'));
    }

GraphQLライブラリにPaginationTypeの型が用意されているので設定します。
Folklore\GraphQL\Support\PaginationType

    public function args() : array
    {
        return [
            'id' => [
                'name' => 'id',
                'type' => Type::id(),
            ],
            'ids' => [
                'name' => 'ids',
                'type' => Type::listOf(Type::id()),
            ],
            // take, page のパラメータを追加
            'take' => [
                'type' => Type::int(),
            ],
            'page' => [
                'type' => Type::int(),
            ],
        ];
    }

takepage のパラメータを定義します。
takeは1ページに表示する件数、pageは何ページ目かの指定です。

    public function resolve($root, $args, $context, ResolveInfo $info) : LengthAwarePaginator
    {
        $query = Post::query();

        if (isset($args['id'])) {
            $query->where('id', $args['id']);
        }

        if (isset($args['ids'])) {
            $query->whereIn('id', $args['ids']);
        }

        // ページネーションの処理を追加
        $perPage = $args['take'] ?? 20;
        $page = $args['page'] ?? 1;

        return $query->paginate($perPage, ['*'], 'page', $page);
    }

paginateメソッドに1ページあたりの取得件数とページ番号を渡してあげればokです。
Illuminate\Pagination\LengthAwarePaginator を返してあげます。

動作確認

{
  posts(take: 3, page: 5) {
    items {
      id
      title
    }
    cursor {
      total
      perPage
      currentPage
      hasPages
    }
  }
}

items で PostType に定義したフィールドを指定します。
また、 cursor で ページネーションの情報を取得できます。

{
  "data": {
    "posts": {
      "items": [
        {
          "id": "13",
          "title": "Voluptas eos ducimus sit blanditiis qui."
        },
        {
          "id": "14",
          "title": "In quas ex et officia est natus incidunt."
        },
        {
          "id": "15",
          "title": "Harum quaerat consequatur placeat nam est veritatis et."
        }
      ],
      "cursor": {
        "total": 500,
        "perPage": 3,
        "currentPage": 5,
        "hasPages": true
      }
    }
  }
}

所感

Laravel + GraphQLでページネーションをどうするか?
と情報を探していたところ、PaginationTypeを追加するIssueがmasterにマージされていたことを発見しました。
https://github.com/Folkloreatelier/laravel-graphql/pull/242

思ったよりシンプルに書けて凄かったです😊
ページネーションのテストコードがとても参考になりましたので参考にしたコード一覧も載せておきます!

参考コード

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
What you can do with signing up
6