Fields
Field behavior comments and nullability control.
Field Behavior Comments
Proto field comments control nullability and type inclusion:
| Comment | Effect |
|---|---|
// 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
| Value | Effect |
|---|---|
NULLABILITY_UNSPECIFIED | Use default behavior |
NULLABLE | Field is nullable |
NON_NULL | Field 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.