何番煎じの話だよって感じですがメモがてら。
基本的にはこちらで書かれてる実装とほぼ同じです。 (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