GraphQLのUnionを使ってみる (Rails)

December 12, 2022

確認環境

$ bundle exec ruby --version
ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin19]
$ bundle exec rails --version
Rails 6.0.4.6
$ bundle info graphql
  * graphql (2.0.13)
	Summary: A GraphQL language and runtime for Ruby
	Homepage: https://github.com/rmosolgo/graphql-ruby
	Path: /Users/xxxxx/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/graphql-2.0.13

データ準備

テーブル定義確認

$ rails db
sqlite> .schema posts
CREATE TABLE IF NOT EXISTS "posts" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar, "description" text, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL);

検証コードを実装

app/graphql/types/query_type.rb

module Types
  class QueryType < Types::BaseObject
    field :start_union, [Types::StartUnion], null: false
    def start_union
      Post.all.limit(3)
    end
  end
end

app/graphql/types/post_type.rb

# frozen_string_literal: true

module Types
  class PostType < Types::BaseObject
    field :id, ID, null: false
    field :title, String
    field :created_at, GraphQL::Types::ISO8601DateTime, null: false
    field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
  end
end

app/graphql/types/post_detail_type.rb

# frozen_string_literal: true

module Types
  class PostDetailType < Types::BaseObject
    field :id, ID, null: false
    field :description, String
  end
end

app/graphql/types/start_union.rb

class Types::StartUnion < Types::BaseUnion
  possible_types Types::PostType, Types::PostDetailType
  def self.resolve_type(object, context)
    if object.id.even?
      Types::PostType
    else
      Types::PostDetailType
    end
  end
end

以下のロジックとしました。

  • idが偶数の場合: PostType
  • idが奇数の場合: PostDetailType

graphiql でクエリを発行する

query {
  startUnion {
    ... on Post {
      id
      title
    }
    ... on PostDetail {
      id
      description
    }
  }
}

取得結果

query {
  startUnion {
    ... on Post {
      id
      title
    }
    ... on PostDetail {
      id
      description
    }
  }
}

SHARE

Profile picture

Written by tamesuu