tommwq.work/aip

AIP-149 未设定域的值

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

在许多消息中,很多域是可选的:用户不需要设定这些域;或者对于输出域,服务可能没有设定这些域。

在大多数情况下,将域设定成默认值(例如 0 )与完全不设定值之间,没有实际区别。但是有时这种区别是有意义的。

指南

使用protocol buffer定义的服务,对于基础类型,当且仅当需要区分将域设置为默认值( 0false 或空字符串)和完全不设定值这两种情况时, 应当 使用 optional 关键字:

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

重要 大多数情况下,服务 不应 需要区分默认值和未设定值;如果备选设计方案不需要进行区分,建议考虑这一方案。实际上,这意味着 optional 应当 仅用于整数和浮点数。

重要 检查域是否存在,与AIP-203中定义的API域行为文档 同。例如,一个使用 optional 标签检查存在性的域, 可以 同时被注解为 google.api.field_behavior = REQUIRED ,如果这个域必须被设定。如果只希望记录服务器感知的域行为,请阅读AIP-203

向后兼容性

添加或删除现有域的 optional 限定符的变更是无法向后兼容的。因为(在某些编程语言中)编译后的API源代码会发生变化。例如在Golang中,添加 optional 后,基础类型域的数据类型变成了指向原来数据类型的指针。原来数据类型为 string 的变成了 *string 。因此这类变更要求客户端和服务器同步改变对变更域的用法,有风险由容易出错。更多信息请参考Protobuf文档

理由

域行为和 optional

域行为注解和 optional 标签不是排斥的,它们解决不同的问题。前者 google.api.field_behavior 侧重于传达服务器对API域的感知,例如域是必需的吗?是不可变的吗?……后者protocol buffer版3的 optional 标签是传输格式和代码生成选项,仅限于域的存在性检查。虽然如果一个域被注解为 google.api.field_behavior = REQUIRED ,又被标记为 optional 可能会让人困惑,但在实践中二者是不相关的,可以合理的同时使用。

修订记录

  • 2024-06-05 添加向后兼容性考虑。
  • 2023-06-20 和域行为文档进行区分。