tommwq的博客

AIP-161 域掩码

· [tommwq@126.com]
编号 161
原文链接 https://google.aip.dev/161
状态 批准
创建日期 2021-03-01
更新日期 2021-03-01

在(使用AIP-134的Update或类似方法)更新资源时,通常需要明确指定哪些域需要更新。服务可以忽略另外的域,即使用户发送了值。

定义一种掩码格式,为每个API处理更具体需求的方案虽然吸引人。但考虑到掩码需求不断变化,明智的做法是使用一种结构化语法,可以透明地进行更新,无需等待界面或客户端升级。

指南

域名字的掩码称为“域掩码”。表示域掩码的域 必须 使用 google.protobuf.FieldMask 类型。域掩码在Update请求(AIP-134)中很常见。

域掩码 必须 始终相对于资源:

警告 将读掩码作为请求消息中独立域(如 google.protobuf.FieldMask read_mask )的方案 已废弃

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

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

读写一致性

如果使用域掩码,其读写行为 必须 自洽:

  • 如果用户使用某个掩码更新资源,然后使用相同掩码读取同一资源,服务 必须 返回完全相同的数据。
  • 类似地,使用某个掩码读取资源,然后用收到数据和相同掩码更新资源的请求 必须 不产生实际修改。

注意 这意味着任何对读请求或写请求有效的掩码, 必须 同时对两者都有效。

设定域掩码

域掩码 必须 允许使用 . 字符遍历指定消息结构中的域。

域掩码始终是相对于资源的,资源直接包含的域(如 titlerating )不需要遍历。遍历用在资源包含消息的时候(如 author.given_name )。

注意 用户 必须 可以指定整个消息域,或消息域的子域: authorauthor.given_name 都有效。

Map域

域掩码 可以 支持使用 . 字符遍历指定Map中的域,只要Map的键是字符串或整数。

域掩码 应当 支持字符串键,处理键不符合域掩码语法的情况。字符串键使用反引号包围。

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;
}

通配符

域掩码 可以 允许在重复域或Map上使用 * 字符,指示集合元素的特定子域:

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

  // The name of the book.
  // Format: publishers/{publisher}/books/{book}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // 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;
}

注意 域掩码 不得 允许通过索引访问重复域的特定元素。如果收到这种请求, 必须 返回 INVALID_ARGUMENT 错误。

只输出域

如果用户(使用通配符或指定包含只输出域的消息)间接在更新掩码中包含了只输出域,服务 必须 忽略随请求输入的任何只输出域,即使请求要求清理或修改它们。

如果用户在更新掩码中直接设定了只输出域,服务 必须 忽略随请求输入的只输出域,即使请求要求清理或修改它们,以便支持同一个域掩码同时用于输入和输出。

无效的域掩码条目

读取数据时,域掩码 可以 忽略指向不存在的值的条目(无论是域不存在,还是服务认定的无效Map键)。

写入数据时,如果条目指向不存在的值,服务 应当 返回 INVALID_ARGUMENT 错误。然而服务 可以 允许删除请求。

修订记录

  • 2023-10-18 更新关于更新掩码中存在只输出域的指南。
  • 2023-07-17update_mask 指南移至AIP-134