AIP-149

Unset field values

In many messages, many fields are optional: the user is not required to provide them, or for output fields, the service might not populate the field.

In most cases, there is no meaningful difference between setting it to a default value (such as 0) as opposed to not setting it at all; however, occasionally this distinction is meaningful.

Guidance

Services defined in protocol buffers should use the optional keyword for primitives if and only if it is necessary to distinguish setting the field to its default value (0, false, or empty string) from not setting it at all:

// A representation of a book in a library.
message Book {
  option (google.api.resource) = {
    type: "library.googleapis.com/Book"
    pattern: "publishers/{publisher}/books/{book}"
  };

  // The name of the book.
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The rating for the book, from 0 to 5.
  // 0 is distinct from no rating.
  optional int32 rating = 2;
}

Important: Services should not need to distinguish between the default value and unset most of the time; if an alternative design does not require such a distinction, it is usually preferred. In practice, this means optional should only ever be used for integers and floats.

Important: Tracking field presence is not the same as documenting API field behavior as defined in AIP-203. For example, a field labeled with optional for presence tracking may also be annotated as google.api.field_behavior = REQUIRED if the field must be set. If you only want to document the server perceived behavior of a field, read AIP-203.

Rationale

field behavior and optional

The field behavior annotation and optional label are not mutually exclusive, because they address different problems. The former, google.api.field_behavior, focuses on communicating the server's perception of a field within the API e.g. if it is required or not, if it is immutable, etc. The latter, proto3's optional, is a wire format and code generation option that is strictly for toggling field presence tracking. While it might be confusing for a field to be simultaneously annotated with google.api.field_behavior = REQUIRED and labeled as optional, they are unrelated in practice and can reasonably be used together.

Changelog

  • 2023-06-20: Differentiate from field behavior documentation