This AIP is currently under review. This means that the editors have read it and are in high-level concurrence, and while it is not yet fully approved, we have a good faith expectation that the AIP will be approved in something close to its current state.

AIP-161

Field masks

Often, when updating resources (using an update method as defined in AIP-134 or something reasonably similar), it is desirable to specify exactly which fields are being updated, so that the service can ignore the rest, even if the user sends new values.

It is tempting to define a mask format to handle the precise needs for each API. However, masking requirements evolve, and therefore it is prudent to use a structured syntax. This allows updates to be able to be made transparently, without waiting for UI or client updates.

Guidance

Update methods (AIP-134) must include an update_mask field, and Get and List methods may include a read_mask field. These are collectively called "field masks", and they use the google.protobuf.FieldMask type.

Field masks must always be relative to the resource:

message UpdateBookRequest {
  // The book to update.
  //
  // The book's `name` field is used to identify the book to be updated.
  // Format: publishers/{publisher}/books/{book}
  Book book = 1 [(google.api.field_behavior) = REQUIRED];

  // The list of fields to be updated.
  // Fields are specified relative to the book
  // (e.g. `title`, `rating`; *not* `book.title` or `book.rating`).
  google.protobuf.FieldMask update_mask = 2;
}

Read-write consistency

Read and write behavior for field masks must be self-consistent if a mask is present:

  • If a user updates a resource with a given mask, and then reads the same resource with the same mask, the exact same data must be returned.
  • Similarly, reading a resource with a given mask and then updating the resource with the returned data and the same mask must be a no-op.

Note: This implies that any mask that is valid for either read or write must be valid for both.

Specifying specific fields

Field masks must permit the specification of specific fields in a defined struct, using the . character for traversal.

Because field masks are always relative to the resource, direct fields on the resource require no traversal (examples: title, rating). Traversal is used when resources contain messages (example: author.given_name).

Note: A user must be able to specify either a field as a whole, or one of its subfields: author and author.given_name are both valid.

Map fields

Field masks may permit the specification of specific fields in a map, if and only if the map's keys are either strings or integers, using the . character for traversal.

Field masks should support string keys that contain characters that are problematic for the field mask syntax, using the backtick character.

message Book {
  // The name of the book.
  // Format: publishers/{publisher}/books/{book}
  string name = 1;

  // Reviews for the back cover. The key is the author of the review,
  // and the value is the text of the review.
  //
  // Valid field masks: reviews, reviews.smith, reviews.`John Smith`
  map<string, string> reviews = 2;
}

Wildcards

Field masks may permit the use of the * character on a repeated field or map to indicate the specification of particular sub-fields in the collection:

message Book {
  // The name of the book.
  // Format: publishers/{publisher}/books/{book}
  string name = 1;

  // The author or authors of the book.
  // Valid field masks: authors, authors.*.given_name, authors.*.family_name
  // Invalid field masks: authors.0, authors.0.given_name
  repeated Author authors = 2;
}

message Author {
  // The author's given name.
  string given_name = 1;

  // The author's family name.
  string family_name = 2;
}

Note: Field masks must not permit accessing a particular element of a repeated field by index, and must return an INVALID_ARGUMENT error if this is attempted.

Output only fields

If a user includes an output only field in an update mask indirectly (by using a wildcard or specifying an overall message that includes an output-only subfield), the service must ignore any output only fields provided as input, even if they are cleared or modified.

If a user directly specifies an output only field in an update mask, the service should ignore the output only fields provided as input, even if they are cleared or modified, to permit the same field mask to be used for input and output. However, the service may choose to error with INVALID_ARGUMENT if the field is modified in input.

Invalid field mask entries

When reading data, field masks should ignore entries that point to a value that can not exist (either a field that does not exist, or a map key that the service considers invalid).

When writing data, field masks should return an INVALID_ARGUMENT error if an entry points to a value that can not exist; however, the service may permit deletions.