graphql-rubyを利用する際、複数のObjectで同一のfieldを共通利用したくなりました。
下記手順で、Interfaceを利用して実現できました。
- BaseInterfaceを定義する
- 共通利用したいfieldをまとめたInterfaceを定義する
- fieldを定義するObjectでInterfaceをimplementsする
なお公式ドキュメントは下記です。詳細はこちらをご参照ください。
https://graphql-ruby.org/type_definitions/interfaces
0. Interfaceとは
Interfaces are lists of fields which may be implemented by object types.
Interfaceとは、Objectによって実装することができるfieldのリストです。
1. BaseInterfaceを定義する
これから定義するInterfaceにおいて、その基底となるBaseInterfaceを定義します。
types/base_interface.rb
module Types::BaseInterface
include GraphQL::Schema::Interface
end
2. 共通利用したいfieldをまとめたInterfaceを定義する
例として、 created_at
, updated_at
というfieldを共通利用したい場合を想定します。
下記のようにInterfaceを定義します。
types/timestamp_interface.rb
module Types::TimestampInterface
include Types::BaseInterface
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
3. fieldを定義するObjectでInterfaceをimplementsする
例として、 User
, Book
というObjectで created_at
, updated_at
というfieldを定義している場合を想定します。
Before
共通化する前は、それぞれ created_at
, updated_at
のfieldを定義していました。
types/user.rb
class Types::User < Types::BaseObject
field :name, String, null: false
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
types/book.rb
class Types::Book < Types::BaseObject
field :title, String, null: false
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
After
先ほど定義した TimestampInterface
をimplementsしました。
こうすることで、 それぞれで created_at
, updated_at
のfield定義が不要になりました。
types/user.rb
class Types::User < Types::BaseObject
implements Types::TimestampInterface
field :name, String, null: false
end
types/book.rb
class Types::Book < Types::BaseObject
implements Types::TimestampInterface
field :title, String, null: false
end