0
1

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 1 year has passed since last update.

graphql-ruby と kaminari を使って オフセットページネーションを簡単にやるやつ

Posted at

何番煎じの話だよって感じですがメモがてら。
基本的にはこちらで書かれてる実装とほぼ同じです。 (Tanakaさん、感謝!)
https://note.com/tana_d/n/n39e2b8dcd4ee

まずはconnection_typeを拡張します。

total_countとかはkaminariが生やしてくれてるやつですね。

class Types::BaseConnection < Types::BaseObject
  include GraphQL::Types::Relay::ConnectionBehaviors

  field :current_page, Int, null: false, description: '現在のページ'
  field :total_count, Int, null: false, description: '総件数'
  field :total_pages, Int, null: false, description: '総ページ数'

  def total_count
    object.items.total_count
  end

  def total_pages
    object.items.total_pages
  end

  def current_page
    object.items.current_page
  end
end

こちらの作者のrmosolgoさんのissueに対するコメントが全てなんですが、
(https://github.com/rmosolgo/graphql-ruby/issues/2829#issuecomment-600140916)

object.items とすると、ActiveRecord::Relation がそのまま返ってくるので、とってきたSQLの全件数とかが返せるようになります。

nodes だとGraphQLのページネーションオブジェクトが返ってくるので、そのページの情報になっちゃうんですよね。これは多くの人が期待するものと若干ズレがある気がする。(というか、使い分けの話)

あとは各resolverでkaminariを呼べるようにしてあげればオフセットページネーションができるし、全件数やページ数なんかも一緒に返せるようになります。

class Resolvers::UsersResolver < Resolvers::BaseResolver
  type Types::UserType.connection_type, null: false

  argument :page, Integer, required: false

  def resolve(page:)
    User.all.page(page)
  end
end

clientからはこんな感じで投げる

query {
  users(page: 1) {
    totalCount
    totalPages
    currentPage
    edges {
      node {
        id
      }
    }
  }
}

オフセットとカーソルが共存できるので利用シーンに合わせてFEと協議して選べますね。

こういう拡張がささっとやれるの、使い勝手いいなあと思って書いてみました。

バージョン
ruby 3.1.1
rails 7.0.2
graphql 2.0.15
kaminari 1.2.2

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?