Skip to Content
Type MappingMessages

Messages

How Protobuf messages are converted to GraphQL types.

Basic Conversion

By default, each Protobuf message generates both an ObjectType and an InputType:

message User { string name = 1; string email = 2; }
type User { name: String email: String } input UserInput { name: String email: String }

Nested Messages

Nested messages use underscore-separated naming:

message User { message Address { string city = 1; } Address address = 1; }
type User { address: User_Address } type User_Address { city: String }

Interface Generation

Use (graphql.object_type).interface = true to generate a GraphQL interface instead of an object type:

message Node { option (graphql.object_type).interface = true; uint64 id = 1; }
interface Node { id: String }

Squashed Union

Use (graphql.object_type).squash_union = true to convert a message with a oneof to a union type:

message Content { option (graphql.object_type).squash_union = true; oneof content { Blog blog = 1; Video video = 2; } }
union Content = Blog | Video

Without squash_union, this would generate:

type Content { content: ContentContent } union ContentContent = Blog | Video

Type Prefix

Add a prefix to all generated type names with (graphql.schema).type_prefix:

option (graphql.schema).type_prefix = "Api"; message User { string name = 1; }
type ApiUser { name: String }

Renaming Types

Override the GraphQL type name with (graphql.object_type).name:

message InternalUser { option (graphql.object_type).name = "User"; string name = 1; }
type User { name: String }

Ignoring Messages

Ignore Both ObjectType and InputType

message Internal { option (graphql.object_type).ignore = true; string data = 1; }

No GraphQL types are generated for this message. Nested messages are still processed.

Ignore InputType Only

message ReadOnlyData { option (graphql.input_type).ignore = true; string value = 1; }
type ReadOnlyData { value: String } # No input type generated

Ignoring Request/Response Messages

Use file-level options to ignore RPC request and response messages:

option (graphql.schema).ignore_requests = true; option (graphql.schema).ignore_responses = true; message GetUserRequest { uint64 id = 1; } message GetUserResponse { User user = 1; }

Messages ending with Request or Response are excluded from generation.

Ignoring Entire Files

option (graphql.schema).ignore = true; message Internal { string data = 1; }

No types are generated from this file.

Partial Input Types

When partial_inputs=true is set in plugin options, additional partial input types are generated with all fields nullable:

message User { // Required. string name = 1; string email = 2; }
input UserInput { name: String! email: String } input UserPartialInput { name: String # Now nullable email: String }

Disable partial inputs for specific messages with (graphql.input_type).no_partial:

message Config { option (graphql.input_type).no_partial = true; string key = 1; string value = 2; }