Skip to Content

Fields

Field behavior comments and nullability control.

Field Behavior Comments

Proto field comments control nullability and type inclusion:

CommentEffect
// Required.Field is non-nullable (!)
// Output only.Field only in ObjectType, excluded from InputType
// Input only.Field only in InputType, excluded from ObjectType

Comments can be combined:

message User { // Required. Output only. uint64 id = 1; // Required. string name = 2; // Input only. string password = 3; // Optional field (no comment) string bio = 4; }
type User { id: String! # Required, included (Output only) name: String! # Required, included # password excluded (Input only) bio: String # Nullable } input UserInput { # id excluded (Output only) name: String! # Required, included password: String # Included (Input only), nullable without Required bio: String # Nullable }

Explicit Nullability Control

Override nullability with proto annotations:

Output Nullability

message Example { string nullable_field = 1 [(graphql.field).output_nullability = NULLABLE]; string non_null_field = 2 [(graphql.field).output_nullability = NON_NULL]; }
type Example { nullableField: String # Forced nullable nonNullField: String! # Forced non-null }

Input Nullability

message Example { string field = 1 [(graphql.field).input_nullability = NON_NULL]; }
input ExampleInput { field: String! }

Partial Input Nullability

When using partial_inputs=true:

message Example { // Required. string always_required = 1 [(graphql.field).partial_input_nullability = NON_NULL]; }
input ExamplePartialInput { alwaysRequired: String! # Stays non-null even in partial input }

Nullability Values

ValueEffect
NULLABILITY_UNSPECIFIEDUse default behavior
NULLABLEField is nullable
NON_NULLField is non-nullable (!)

Repeated Fields

Repeated fields always generate non-null lists with non-null items:

message Example { repeated string tags = 1; }
type Example { tags: [String!]! }

ID Fields

Use (graphql.field).id = true to use GraphQL ID type:

message User { // Required. Output only. uint64 id = 1 [(graphql.field).id = true]; }
type User { id: ID! }

Renaming Fields

Override the field name with (graphql.field).name:

message User { string user_name = 1 [(graphql.field).name = "name"]; }
type User { name: String # Not userName }

By default, field names are converted from snake_case to camelCase:

message Example { string first_name = 1; # → firstName string lastName = 2; # → lastName (preserved) }

Ignoring Fields

Exclude fields from generation:

message User { string name = 1; string internal_data = 2 [(graphql.field).ignore = true]; }
type User { name: String # internalData not included }

Skip Resolver

Omit resolver implementation:

message User { string computed_field = 1 [(graphql.field).skip_resolver = true]; }

This generates the field type but skips the resolver, allowing you to implement it manually.