A union type is a set of object types which may appear in the same spot. Here’s a union, expressed in GraphQL Schema Definition Language (SDL):
union MediaItem = AudioClip | VideoClip | Image | TextSnippet
This might be used on a search field, for example:
searchMedia(term: "puppies") {
... on AudioClip {
duration
}
... on VideoClip {
previewURL
resolution
}
... on Image {
thumbnailURL
}
... on TextSnippet {
teaserText
}
}
Here, the searchMedia
field returns [MediaItem!]
, a list where each member is part of the MediaItem
union. So, for each member, we want to select different fields depending on which kind of object that member is.
Interfaces are a similar concept, but in an interface, all types must share some common fields. Unions are a good choice when the object types don’t have any significant fields in common.
Since union members share no fields, selections are always made with typed fragments (... on SomeType
, as seen above).
Unions extend GraphQL::Schema::Union
. First, make a base class:
class Types::BaseUnion < GraphQL::Schema::Union
end
Then, extend that one for each union in your schema:
class Types::CommentSubject < Types::BaseUnion
comment "TODO comment on the union"
description "Objects which may be commented on"
possible_types Types::Post, Types::Image
# Optional: if this method is defined, it will override `Schema.resolve_type`
def self.resolve_type(object, context)
if object.is_a?(BlogPost)
Types::Post
else
Types::Image
end
end
end
The possible_types(*types)
method accepts one or more types which belong to this union.
Union classes are never instantiated; At runtime, only their .resolve_type
methods may be called (if defined).
For information about .resolve_type
, see the Interfaces guide.