4
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 3 years have passed since last update.

Graphql-RubyでInterfaceTypeを使うpart2

Last updated at Posted at 2021-02-17

前回、Graphql-RubyでActiveRecordのInterfaceを定義しました。(前回はこちら)
今回は、ポリフォーリズムとしてのInterfaceを利用してみたいと思います。

#設定
あるシステムのエンドユーザは、店員(staff)と社員(employee)の2つのオブジェクトによって利用されるとしましょう。この2つのオブジェクトは,nameとemailという共通するインスタンス変数を持っています。よって、この2つをInterfaceとして定義します。

#Interface Type
以下のようにstaffとemployeeのインターフェースとしてUserInterfaceを定義できます。

interface_type.rb
module InterfaceTypes
  module UserInterface
    include InterfaceTypes::BaseInterface
    description 'user(staff and employee) interface'

    field :name, String, null: false
    field :email, String, null: false

    definition_methods do
      def resolve_type(object, _context)
        case object
        when ::Employee
          ObjectTypes::EmployeeType
        when ::Staff
          ObjectTypes::StaffType
        else
          raise "Unexpected UserType: #{object.inspect}"
        end
      end
    end
  end
end

まず、fieldで共通するプロパティ を定義します。その後resolve_typeでgraphqlでフロントにかえすオブジェクトによってEmployee Typeを返すかStaff Typeを分岐させています。

#クエリー定義
フロント側でのクエリー定義は以下のようになります。

query{
  user {
    id
    name
    email
    __typename ## employee or staffがstringで渡される
    ... on Employee { ##employeeのみに存在するフィールド
      role
    ... on Staff { ##staffのみに存在するフィールド
      shopName
    }
  }
}

上記のように共通するフィールド以外は個別に定義できます。
__typenameはgraphql-rubyが自動で付けてくれるフィールドで、どちらのオブジェクトなのかを判別することができます。

#なぜInterfaceTypeを定義するか

返すObjectを意識しなくて良い

Interface TypeはGraphqlのクエリーの戻り値がstaffかemployeeかを意識したくない時に利用できます。例えば、Userのログインクエリーをフロントから叩きたい場合を考えてみましょう。
フロント側はユーザがemployeeかstaffかを意識せずにloginの同じクエリーを叩き、戻り値としてstaffかemployeeを返します。interface Typeを定義していないとログインユーザに返すオブジェクトによって別々にクエリーを定義する必要があります。しかし、Interface Typeを定義しておくと返り値としてUserInterfaceTypeと定義しておけば、どちらがログインしても対応することができます。

フロント側でもInterfaceTypeを定義できる

フロント側でtypescriptを使っている場合、graphql-codegenなどの自動型生成のプラグインを使うとUserInterfaceTypeを定義してくれます。これによって、フロント側でもログインユーザがstaffかempolyeeかを意識せずにemailやnameにアクセスできます。
また、typenameプロパティ によってstaffかemployeeかを判別して表示するページを切り替えたりできます。

4
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
4
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?