見出し画像

graphql-batchを使用して感じる利点

graphql-rubyと一緒にgraphql-batchを利用しているので使ってみて感じた利点を書いておきます。

graphql-batchとは

Shopifyが主になって開発しているGemで、batchの名の通り一括処理をするためのライブラリ。

他の言語だとライブラリにdataloaderという名前がつけられているものと同じようなものです。

使い方とかはGitHubに書かれてるのでそちらを参照ください。

graphql-batchを使って変わった点

Queryの実装で includes をほぼほぼ使わなくなったというのがあります。

Typeクラスの各fieldでgraphql-batchを利用して関連するデータを取得するので、Queryの処理でわざわざ includes を書くことがなくなりました。

Queryの処理では、検索に必要なテーブルだけを見て、単一のモデルクラス(Userとか)を返してあとはgraphql-batchによしなにデータを取得したりしなかったりしてもらうという感じです。

逆にMutationではクラアントからのInputによって大きく操作対象のデータが変わるというのが稀なので、普通に includes を使っています。ただし、レスポンスを返す際にデータを取得する必要がある場合は、Queryと同じく、Mutationの処理自体では最低限のデータしか取らないようにしています。

graphql-batchを良かった点

N+1が効率的に解決できるのはもちろん良かったですが、それ以外に2点良かったと思うことがあります(全部graphql-batch固有の話ではないですが)。

Typeクラスの取り回しが良くなる

Typeクラスと呼んでいるのは↓のようなGraphQLのスキーマとして表されるようなクラスのことですが、

class Types::UserType < GraphQL::Schema::Object
  field :id, Int, null: false
  field :name, String, null: false
  field :plans, [Types::Plan], null: false
  
  def plan
    AssociationLoader.for(User, :plans).load(object)
  end
end

graphql-batchを使っていると、このUserTypeを返すQuery/MutationはUserTypeのもととなるUserクラスのインスタンスさえ返すことができれば良いということになります。

GraphQLでAPIを作っていると、色々なところで同じTypeを使いまわすことになりますが、このTypeを返す時はAとBとCとDからデータを取っておかないと動かなくて…のようなことを考える必要がなくなり、かなり取り回しが楽になりました。

各データを取得する処理を実装する時に考えるべきことが少なくなる

graphql-batchを使うと、基本的に「1fieldに必要なデータのみを取ってくる」ということに集中することができるようになります。

いくつものテーブルやAPIが入り混じった複雑なデータ取得をして大きなJSONを返す実装をするよりも、この1つのfieldを満たすデータを取ってくるにはどうすべきかと考えて実装をし、それを組み合わせる方がはるかに簡単で、不具合を生んでしまう可能性も低くなります。

また、ActiveRecordでガッと取ってきてモデルクラスをインスタンス化して…のような処理を書き連ねるのではなく、fieldのデータを満たすために最適な処理を書くことにも繋がりやすいように思いました。


以上、graphql-batchを数ヶ月使ってみて感じた利点でした。

この記事が気に入ったらサポートをしてみませんか?