tommwq.work/aip

AIP-203 域行为文档

· [tommwq@126.com]
编号 203
原文链接 https://google.aip.dev/203
状态 批准
创建日期 2018-07-17
更新日期 2018-07-17

在定义protocol buffer中的域时,按惯例要向用户解释域行为的某些方面(例如域是必需的还是可选的)。此外,让其他工具理解域行为也很有用(例如优化客户端库签名)。

指南

API使用 google.api.field_behavior 注解来描述已知的域行为,例如域是必需或不可变的。

// 待识别语音数据。
RecognitionAudio audio = 2 [(google.api.field_behavior) = REQUIRED];
  • API 必须 在请求使用的消息或子消息的每个域上添加 google.api.field_behavior 注解。
  • 注解 必须 包含准确描述域行为的所有 google.api.FieldBehavior 值。
    • 不得 使用 FIELD_BEHAVIOR_UNSPECIFIED
  • API 必须 至少使用 REQUIREDOPTIONALOUTPUT_ONLY 之一。

警告 尽管 field_behavior 不会影响协议级别的行为,但许多客户端(例如CLI和SDK)依赖它们生成代码。在添加新域时,请仔细审查并考虑哪些值是相关联的。

为了向后兼容,没有注解的域被认为是 OPTIONAL 。尽管如此, 不得 省略此注解。

注意 本文档中给出的词汇仅用于 描述 ,本身不产生任何校验。目的是为客户端统一记录域行为。

嵌套消息的域行为

嵌套消息上的 google.api.field_behavior 注解与上级消息注解无关。

例如,嵌套消息可以具有 REQUIRED 域行为,而上级域可以是 OPTIONAL

message Title {
  string text = 1 [(google.api.field_behavior) = REQUIRED];
}

message Slide {
  Title title = 1 [(google.api.field_behavior) = OPTIONAL];
}

在上述情况下,如果设定了 title ,则 text 域是必需的。

词汇表

标识符

IDENTIFIER 表示资源消息中的域用于标识资源, 必须 添加到 name 域, 不得 添加到任何其他域(参考表示资源名字的域)。

IDENTIFIER 值表示在创建方法的上下文中,域不作为输入域(即 OUTPUT_ONLY ),同时也表示在接受资源作为主要输入的修改方法(如标准更新)中,域作为 IMMUTABLE 不可变输入。

此注解 不得 用于消息对其他资源的引用。

不可变的

IMMUTABLE 表示域在资源创建后不可改变。这可以应用于输入或输出、必需或可选的域。

如果服务在更新请求(或类似请求)中收到不可变域,如果域包含在更新掩码中,并且新值与现值一致,服务 应当 忽略域值。但如果请求尝试修改值,服务 应当 返回 INVALID_ARGUMENT 错误。

不可变域的潜在用例(这不是一个详细列表)包括:

  • 应用程序生命周期内,不可修改的资源属性(例如磁盘类型)。

注意 “某些条件下不可变”的域 不得 使用不可变注解。

只输入域

INPUT_ONLY 表示域只在请求中出现,不会包含在输出中。

此外, 应当 只将资源消息或其包含消息中的域注解为只输入域。请注意,请求消息(通常以 Request 结尾、仅作为远程过程调用参数)中的域 不应 注解为只输入域,它们原本就是。

只输入域的潜在用例(这不是一个详细列表)包括:

警告 只输入域很少见,应谨慎使用。

可选域

使用 OPTIONAL 表示域不是必需的。

如果域是请求消息(作为远程过程调用参数的消息,通常以 Request 结尾)或其子消息中的域, 可以 注解为可选的。

只输出域

OUTPUT_ONLY 表示域在应答中提供,而在请求中包含域不会产生任何效果(服务器 必须 清除输入中此域的任何值,并且 不得 由于输入中存在此域的值抛出错误)。同样的,服务 必须 忽略更新域掩码中的只输出域(参考AIP-161)。

此外, 应当 只将资源消息或其树形结构更下方消息中的域注解为只输出域。请注意,应答消息中的域(通常以 Response 结尾的消息,仅作为远程过程调用的返回值) 不应 注解为只输出域,它们本来就是。

只输出域 可以 设置为空值,如果合适。

只输出域的潜在用例(这不是一个详细列表)包括:

  • 创建或更新时间戳。
  • 基于原始用户输入的派生或结构化信息。
  • 由服务分配的无法修改的资源属性。

必需域

REQUIRED 表示域 必须 存在于请求或资源之中(设置为非空值)。

应当 只在以下情况被注解为必需域:

  • 它是用户作为输入提供的某个资源上的域。只有当“真值”被 存储 后,资源才生效。
    • 创建资源时,*必须* 在创建请求中提供域值。
    • 更新资源时,如果域不在掩码中,用户可以省略域,表示不会修改域(否则 必须 提供)。
  • 它是请求消息上的域(作为远程过程调用参数的消息,通常以 Request 结尾)。此时 必须 在请求中提供值,否则服务 必须 返回错误(通常是 INVALID_ARGUMENT )。

我们定义上述术语“真值”如下:

  • 对于原始类型,值不为 00.0 、空字符串/字节和 false
  • 对于重复域映射,至少有一个条目。
  • 对于消息,至少包含一个“真值”域。

在表示下列域时,域 不应 注解为必需域:

  • 始终存在于应答中的域。
  • 在某些条件下必需的域。
  • 从未作为用户输入的消息(包括资源消息)上的域。

注意 在大多数情况下,空值(如布尔值 false 、整数 0 或枚举的未指定值)无法与未设定值进行区分,因此将必需域设置为空值会产生错误。由此推论,必需的布尔域必须设置为 true

无序列表

在资源的重复域上使用 UNORDERED_LIST 表示服务不保证列表中条目的顺序。

如果服务不保证列表中元素的顺序与用户发送的顺序一致,包括服务将代替用户对列表进行排序的情况,域 应当 注解为无序列表。

包含无序列表的资源 可以 按稳定顺序返回列表,也 可以 按随机的、不稳定的顺序返回列表。

向后兼容性

添加或更改 google.api.field_behavior 值可以表示API中的语义变更,现有客户端可能认为这是不兼容的。以下是 google.api.field_behavior 的不向后兼容变更的示例:

  • REQUIRED 添加到之前被认为是 OPTIONAL (隐式或其他方式)的域
  • 将注解为 REQUIRED 的新域添加到现有请求消息中
  • OUTPUT_ONLY 添加到之前作为输入的域
  • INPUT_ONLY 添加到之前作为输出的域
  • IMMUTABLE 添加到之前被认为是可变的域
  • 从之前作为输入的域中删除 OUTPUT_ONLY
  • 从现有域中删除 IDENTIFIER

一些更改是向后兼容的,如下所示:

  • OPTIONAL 添加到现有域
  • IDENTIFIER 添加到现有的 name
  • 将现有域从 REQUIRED 改为 OPTIONAL
  • 将现有域从 OUTPUT_ONLYIMMUTABLE 改为 IDENTIFIER
  • 从现有域中删除 REQUIRED
  • 从之前在应答中排除的域中删除 INPUT_ONLY
  • 从之前被认为是不可变的域中删除 IMMUTABLE

理由

标识符域行为

资源名字是每个合规资源的主要标识符,从未由用户在创建时完整构造。这些域通常被指定为 OUTPUT_ONLY 域行为。然而,在资源本身是主要请求内容的情况下,它们也经常作为主要标识符被消费。因此不能作为 OUTPUT_ONLY 。此外,在变更请求(如标准更新)中,资源名字作为主要标识符,不能就地更改。这些域通常被指定为 IMMUTABLE 域行为。这些冲突,以及上下文相关的域行为,意味着需要一个新值来单独表达资源名域的行为。

要求注解集合

请求消息中使用的域必须要么是输入要么是输出。

在输出的情况下, OUTPUT_ONLY 注解就足够了。

在输入的情况下,域要么是必需的,要么是可选的,因此应该至少具有 REQUIREDOPTIONAL 注解。仅提供 INPUT_ONLY 不能表达域的必要性,因此仍然需要指定 REQUIREDOPTIONAL

要求域行为

通过为每个域包含域行为注解,资源表现出的整体行为更清晰。清晰的域行为增强了程序化客户端和用户理解。

要求注解还迫使API生产者在最初编写API时就明确考虑其行为。

首次发布后修改域行为可能导致客户端出现不向后兼容变更。例如,将可选域改为必需域会导致远程过程调用或声明式客户端中的资源的方法签名发生不向后兼容变更。关于详细的兼容性指南,请参考向后兼容性部分。

历史

在2023年5月,field_behavior成为强制性指南。此前注解经常被省略。注解值被用于生成高质量客户端。此外,在主要版本内添加或修改某些field_behavior值可能是不向后兼容的。关于更详细的兼容性指南,请参考向后兼容性部分。

在编写API时要求field_behavior的好处超过了不这样做时,客户端和API用户的成本。

修订记录

  • 2023-09-14 明确嵌套消息的行为和上级消息的行为是独立的。
  • 2023-08-25 添加关于 IDENTIFIER 的指南。
  • 2023-07-20 在新章节中买描述兼容性指南。
  • 2023-05-24 明确 IMMUTABLE 并不意味着输入或必需。
  • 2023-05-10 添加要求注解的指南。
  • 2020-12-15 添加 UNORDERED_LIST 指南。
  • 2020-05-27 明确在更新中接收不可变域时的行为。
  • 2019-12-05 添加关于域掩码中只输出域的指南。
  • 2019-06-18 使用机器可读的注解,而非注释。