Oneofs
How Protobuf oneofs are converted to GraphQL union types.
Basic Conversion
A oneof generates a GraphQL union type:
message Media {
string title = 1;
oneof content {
Image image = 2;
Video video = 3;
}
}
message Image {
string url = 1;
}
message Video {
string url = 1;
int32 duration = 2;
}type Media {
title: String
content: MediaContent
}
union MediaContent = Image | Video
type Image {
url: String
}
type Video {
url: String
duration: Int
}Union Naming
The union name combines the message name and oneof name:
| Message | Oneof | Union Name |
|---|---|---|
Media | content | MediaContent |
User | profile_type | UserProfileType |
Required Oneofs
Use // Required. comment to make the union non-nullable:
message Media {
// Required. disallow not_set.
oneof content {
Image image = 1;
Video video = 2;
}
}type Media {
content: MediaContent!
}Squashed Unions
Use (graphql.object_type).squash_union = true to convert the entire message to a union:
message Content {
option (graphql.object_type).squash_union = true;
oneof content {
Blog blog = 1;
Video video = 2;
}
}union Content = Blog | VideoThis is useful for polymorphic types where the wrapper message adds no value.
Without squash_union
type Content {
content: ContentContent
}
union ContentContent = Blog | VideoWith squash_union
union Content = Blog | VideoOneofs in Input Types
In input types, oneof fields are flattened as optional fields (not a union):
message CreateMediaInput {
oneof content {
ImageInput image = 1;
VideoInput video = 2;
}
}input CreateMediaInputInput {
image: ImageInputInput
video: VideoInputInput
}Only one field should be provided at a time.
Ignoring Oneofs
Exclude a oneof from generation:
message Example {
oneof internal {
option (graphql.oneof).ignore = true;
TypeA a = 1;
TypeB b = 2;
}
}Ignoring Individual Oneof Fields
Exclude specific fields from the union:
message Media {
oneof content {
Image image = 1;
Video video = 2;
LegacyFormat legacy = 3 [(graphql.field).ignore = true];
}
}union MediaContent = Image | Video
# LegacyFormat not includedNon-Message Oneof Fields
By default, oneofs with scalar types generate unions that include those scalars. Use ignore_non_message_oneof_fields=true to exclude them:
message Example {
oneof value {
string text = 1; # Excluded with option
int32 number = 2; # Excluded with option
CustomType custom = 3; # Included
}
}opt:
- ignore_non_message_oneof_fields=trueThis is useful when you only want message types in unions.