17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravel 5.7 + GraphQL(Pagination編)

Last updated at Posted at 2018-10-19

今回は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

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

参考コード

17
6
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
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?