🌐

graphql-rubyでフィールド名と別名のメソッドを使用したい場合はmethodオプションを使うと便利

2022/12/25に公開

はじめに

今回は、graphql-rubyで fieldmethod オプションを使って、フィールド名と別名のメソッドを使用する方法について書きたいと思います。

https://github.com/rmosolgo/graphql-ruby

graphql-rubyのfield

まず、graphql-rubyでは、field というDSLでフィールドを定義すると、渡されたオブジェクトの同名のメソッドを呼び出してフィールドを解決してくれます。(ハッシュの場合はキー名として検索してくれます)

つまり、以下のように field が定義されていた場合、top_score フィールドを返す際に、渡されたオブジェクトの top_score メソッドが呼び出されます。

field :top_score, Integer, null: false

GraphQLのフィールド名とオブジェクトのメソッド名が一致している場合は何も書くことなくフィールドが解決できてとても便利なのですが、Rubyの慣習でメソッド名に ? を付けている場合や他の使用箇所との兼ね合いからフィールド名とメソッド名を一致させられない場合もあります。

fieldのmethodオプション

そんな時は、fieldmethod オプションを使用して別名のメソッドを指定することができます。

以下のように書くと、top_score のフィールドを解決する際に、渡されたオブジェクトの best_score メソッドが呼び出されます。

field :top_score, Integer, null: false, method: :best_score

これによって、フィールド名と別名のメソッドであっても呼び出すことができるようになります。

詳細はドキュメントの以下の箇所に書かれています。

https://graphql-ruby.org/fields/introduction.html#field-resolution

実際の使用例

よくあるユースケースを見ていきましょう。

例えば、以下のようなenumで公開ステータスを定義しているPostモデルについて考えます。

app/models/post.rb
class Post < ApplicationRecord
  enum :status, { draft: 0, published: 1 }
end

enumによってモデルには published? メソッドが定義されるので、これを利用してGraphQLで公開されているかどうかのBooleanの値を取得したいとします。

この場合、GraphQLのフィールド名には ? は使用できないため、 is_published のようなフィールド名にすることが多いかと思います。

methodオプションを使わない場合

method オプションを使わなくても、以下のように紐付けを行うメソッドを定義することでやりたいことは実現できます。

app/graphql/types/post_type.rb
module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: false
    field :is_published, Boolean, null: false
    
    def is_published
      object.published?
    end
  end
end

しかし、1つくらいならまだよいですが、これがどんどん増えてくるとクラスの見通しが悪くなっていきます。

methodオプションを使った場合

これを method オプションを使うことで、以下のように余分なメソッドを定義することなく書くことができます。

app/graphql/types/post_type.rb
module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: false
    field :is_published, Boolean, null: false, method: :published?
  end
end

ドキュメントをしっかりと読めば書いてくれてあるのですが、最初このオプションを知らずにObjectTypeのクラスの中に無駄なメソッドをたくさん定義してしまっていました。

method オプションを使うことでシンプルに書けるようになるので、使える場所では積極的に使っていきたいですね。

まとめ

今回は、graphql-rubyの fieldmethod オプションについて紹介しました。

意外とググっても情報が出てこなかったので、同じように困ってる方の参考になれば幸いです。

Discussion