LoginSignup
1
1

More than 1 year has passed since last update.

GraphQLでページネーションを実装する際はGraphQL Cursor Connections Specificationを参考にしよう!

Last updated at Posted at 2022-06-01

はじめに

NestJS x GraphQLで実装したユーザー一覧を取得するAPIにページング機能をつけてNext.js x URQLで呼び出そうとしたらうまくいかなかったので躓いたところを記録として残しておきます。

この記事が同様の問題で悩んでいる人の助けになれば嬉しいです。

TL;DR

環境

ツール・ライブラリ 用途 バージョン
Next.js フロントエンドとして利用 12.1.0
NestJS サーバーサイドとして利用 8.0.0
GraphQL Code Generator コード自動生成ツール 2.6.2
URQL GraphQL Clientのライブラリ 2.2.0
node.js フロント、サーバーサイドの実行環境 v16.14.0
ページネーションの方式 Cursor-based pagination

課題

NestJSで作ったページネーションをgraphql code gen x URQLを使ってWeb側で表示するような実装をしようとしていました。

基本的な書き方は以下を参考にしたのですが、いざ自分の環境でも再現させようとすると追加のn件を取得することができませんでした。

見ての通り、Fetch moreをクリックしても次のn件が表示されません。

その時に設定していたリクエストパラメータは以下になります

Request
query Users($paginatedUsersInput: PaginatedUsersInput) {
  users(paginatedUsersInput: $paginatedUsersInput) {
    ...paginatedUsers
  }
}

fragment paginatedUsers on PaginatedUsersOutput {
  edges {
    node {
      ...userProfile
    }
  }
  pageInfo {
    endCursor
    hasNext
  }
}

fragment userProfile on UserOutput {
  nickname
  uid
}
Response
{
  edges: {
    node: User
  }
  pageInfo: {
    endCursor: string
    hasNext: boolean
  }
}

解決方法

InputとOutputをGraphQL Cursor Connections Specificationに合わせることで解決することができました。

実際に変えてみたコードがこちら↓

Request
# paginatedUsersInputを除外してfirst, afterだけにする
query Users($first: Int, $after: String) {
  users(first: $first, after: $after) {
    ...paginatedUsers
  }
}

fragment userProfile on UserOutput {
  # ~~ 省略 ~~
Response
{
	edges: {
		// cursorを追加
		cursor: string
		node: User
	}
	pageInfo: {
		endCursor: string
		// hasNextからhasNextPageに変更
		hasNextPage: boolean
	}
}

無事正常にFetchMoreができました!

注意点

今回採用したページネーションの方式はCursor-basedであって、Offset-basedTime-basedには適用できないので注意してください。

余談

ページングの実装をしたことがなかったので今回理解しながら書けるようになれて良かったです!

引き続き開発を続けていこうと思います!

ではまた!

参考記事

1
1
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
1
1