Protocol Buffers 知名类型
索引
Any
(消息)Api
(消息)BoolValue
(消息)BytesValue
(消息)DoubleValue
(消息)Duration
(消息)Empty
(消息)Enum
(消息)EnumValue
(消息)Field
(消息)Field.Cardinality
(枚举)Field.Kind
(枚举)FieldMask
(消息)FloatValue
(消息)Int32Value
(消息)Int64Value
(消息)ListValue
(消息)Method
(消息)Mixin
(消息)NullValue
(枚举)Option
(消息)SourceContext
(消息)StringValue
(消息)Struct
(消息)Syntax
(枚举)Timestamp
(消息)Type
(消息)UInt32Value
(消息)UInt64Value
(消息)Value
(消息)
以“Value
”结尾的知名类型是其他类型的包装消息,例如 BoolValue
和 EnumValue
。这些现在已过时。如今使用包装器的唯一原因可能是
- 与已使用它们的现有消息进行线兼容。
- 如果您想将标量值放入
Any
消息中。
在大多数情况下,有更好的选择
- 对于新消息,最好使用常规的显式存在字段(在 proto2/proto3 中为
optional
,在 edition >= 2023 中为常规字段)。 - 扩展通常比
Any
字段是更好的选择。
Any
Any
包含任意序列化消息以及描述序列化消息类型的 URL。
JSON
Any
值的 JSON 表示使用反序列化嵌入消息的常规表示,并带有一个附加字段 @type
,其中包含类型 URL。示例:
package google.profile;
message Person {
string first_name = 1;
string last_name = 2;
}
{
"@type": "type.googleapis.com/google.profile.Person",
"firstName": <string>,
"lastName": <string>
}
如果嵌入的消息类型是知名类型且具有自定义 JSON 表示,则该表示将被嵌入,并添加一个字段 value
,该字段除了 @type
字段外还包含自定义 JSON。示例(对于消息 google.protobuf.Duration
):
{
"@type": "type.googleapis.com/google.protobuf.Duration",
"value": "1.212s"
}
字段名 | Type | 描述 |
---|---|---|
type_url | 字符串 | 一个 URL/资源名称,其内容描述了序列化消息的类型。 对于使用
除了 |
值 | 字节 | 必须是上述指定类型的有效序列化数据。 |
Api
Api 是 protocol buffer 服务的轻量级描述符。
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 此 api 的完全限定名称,包括包名后跟 api 的简单名称。 |
方法 | Method | 此 api 的方法,顺序未指定。 |
选项 | Option | 附加到 API 的任何元数据。 |
版本 | 字符串 | 此 api 的版本字符串。如果指定,必须具有 版本控制方案使用语义版本控制,其中主版本号表示破坏性更改,次版本号表示附加的非破坏性更改。两个版本号都是向用户发出信号,告知他们不同版本之间有什么期望,并且应根据产品计划仔细选择。 主版本号也反映在 API 的包名中,包名必须以 |
source_context |
| 此消息表示的 protocol buffer 服务的源上下文。 |
mixins |
| 包含的 API。参见 Mixin 。 |
语法 | Syntax | 服务的源语法。 |
BoolValue
bool
的包装消息。
BoolValue
的 JSON 表示是 JSON true
和 false
。
字段名 | Type | 描述 |
---|---|---|
值 | bool | 布尔值。 |
BytesValue
bytes
的包装消息。
BytesValue
的 JSON 表示是 JSON 字符串。
字段名 | Type | 描述 |
---|---|---|
值 | 字节 | 字节值。 |
DoubleValue
double
的包装消息。
DoubleValue
的 JSON 表示是 JSON 数字。
字段名 | Type | 描述 |
---|---|---|
值 | double | 双精度浮点值。 |
Duration
Duration 表示一个有符号的固定长度时间跨度,以秒数和纳秒分辨率的秒分数表示。它独立于任何日历以及“日”或“月”等概念。它与 Timestamp 相关,因为两个 Timestamp 值之间的差是一个 Duration,并且可以从 Timestamp 中添加或减去。范围约为 +-10,000 年。
示例 1:用伪代码计算两个 Timestamps 的 Duration。
Timestamp start = ...;
Timestamp end = ...;
Duration duration = ...;
duration.seconds = end.seconds - start.seconds;
duration.nanos = end.nanos - start.nanos;
if (duration.seconds < 0 && duration.nanos > 0) {
duration.seconds += 1;
duration.nanos -= 1000000000;
} else if (duration.seconds > 0 && duration.nanos < 0) {
duration.seconds -= 1;
duration.nanos += 1000000000;
}
示例 2:用伪代码计算 Timestamp + Duration 的 Timestamp。
Timestamp start = ...;
Duration duration = ...;
Timestamp end = ...;
end.seconds = start.seconds + duration.seconds;
end.nanos = start.nanos + duration.nanos;
if (end.nanos < 0) {
end.seconds -= 1;
end.nanos += 1000000000;
} else if (end.nanos >= 1000000000) {
end.seconds += 1;
end.nanos -= 1000000000;
}
Duration
的 JSON 表示是一个以 s
结尾表示秒数的 String
,前面是秒数,纳秒表示为小数秒。
字段名 | Type | 描述 |
---|---|---|
秒 | int64 | 时间跨度的有符号秒数。必须在 -315,576,000,000 到 +315,576,000,000(含)范围内。 |
纳秒 | int32 | 时间跨度的纳秒分辨率的有符号秒分数。小于一秒的 Duration 表示为 0 seconds 字段和一个正或负的 nanos 字段。对于一秒或更长时间的 Duration,nanos 字段的非零值必须与 seconds 字段的符号相同。必须在 -999,999,999 到 +999,999,999(含)范围内。 |
Empty
一个通用的空消息,您可以重复使用它,以避免在 API 中定义重复的空消息。一个典型示例是将其用作 API 方法的请求或响应类型。例如:
service Foo {
rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
}
Empty
的 JSON 表示是空的 JSON 对象 {}
。
Enum
枚举类型定义
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 枚举类型名称。 |
枚举值 | EnumValue | 枚举值定义。 |
选项 | Option | Protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
语法 | Syntax | 源语法。 |
EnumValue
枚举值定义。
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 枚举值名称。 |
编号 | int32 | 枚举值编号。 |
选项 | Option | Protocol buffer 选项。 |
Field
消息类型中的单个字段。
字段名 | Type | 描述 |
---|---|---|
类型 | Kind | 字段类型。 |
基数 | Cardinality | 字段基数。 |
编号 | int32 | 字段编号。 |
名称 | 字符串 | 字段名称。 |
type_url | 字符串 | 消息或枚举类型的字段类型 URL,不带模式。示例:"type.googleapis.com/google.protobuf.Timestamp" 。 |
oneof_index | int32 | 字段类型在 Type.oneofs 中的索引,用于消息或枚举类型。第一个类型的索引为 1;零表示该类型不在列表中。 |
packed | bool | 是否使用备用的 packed 线表示。 |
选项 | Option | Protocol buffer 选项。 |
json_name | 字符串 | 字段 JSON 名称。 |
default_value | 字符串 | 此字段默认值的字符串值。仅限 Proto2 语法。 |
Cardinality
字段是 optional、required 还是 repeated。
枚举值 | 描述 |
---|---|
CARDINALITY_UNKNOWN | 用于基数未知的字段。 |
CARDINALITY_OPTIONAL | 用于 optional 字段。 |
CARDINALITY_REQUIRED | 用于 required 字段。仅限 Proto2 语法。 |
CARDINALITY_REPEATED | 用于 repeated 字段。 |
Kind
基本字段类型。
枚举值 | 描述 |
---|---|
TYPE_UNKNOWN | 字段类型未知。 |
TYPE_DOUBLE | 字段类型 double。 |
TYPE_FLOAT | 字段类型 float。 |
TYPE_INT64 | 字段类型 int64。 |
TYPE_UINT64 | 字段类型 uint64。 |
TYPE_INT32 | 字段类型 int32。 |
TYPE_FIXED64 | 字段类型 fixed64。 |
TYPE_FIXED32 | 字段类型 fixed32。 |
TYPE_BOOL | 字段类型 bool。 |
TYPE_STRING | 字段类型 string。 |
TYPE_GROUP | 字段类型 group。仅限 Proto2 语法,且已弃用。 |
TYPE_MESSAGE | 字段类型 message。 |
TYPE_BYTES | 字段类型 bytes。 |
TYPE_UINT32 | 字段类型 uint32。 |
TYPE_ENUM | 字段类型 enum。 |
TYPE_SFIXED32 | 字段类型 sfixed32。 |
TYPE_SFIXED64 | 字段类型 sfixed64。 |
TYPE_SINT32 | 字段类型 sint32。 |
TYPE_SINT64 | 字段类型 sint64。 |
FieldMask
FieldMask
表示一组符号字段路径,例如:
paths: "f.a"
paths: "f.b.d"
此处 f
表示某个根消息中的字段,a
和 b
表示在 f
中找到的消息中的字段,而 d
表示在 f.b
中的消息中找到的字段。
字段掩码用于指定应该由 get 操作(一个 *投影*)返回或由更新操作修改的字段子集。字段掩码还具有自定义 JSON 编码(见下文)。
投影中的字段掩码
当 FieldMask
指定一个 *投影* 时,API 将过滤响应消息(或子消息),使其仅包含掩码中指定的那些字段。例如,考虑这个“未掩码前”的响应消息:
f {
a : 22
b {
d : 1
x : 2
}
y : 13
}
z: 8
在应用上一个示例中的掩码后,API 响应将不包含字段 x、y 或 z 的特定值(它们的值将被设置为默认值,并在 proto 文本输出中省略)。
f {
a : 22
b {
d : 1
}
}
除了字段掩码的最后一个位置外,不允许出现 repeated 字段。
如果 get 操作中不存在 FieldMask
对象,则该操作应用于所有字段(如同指定了所有字段的 FieldMask)。
注意,字段掩码不一定适用于顶级响应消息。在 REST get 操作中,字段掩码直接应用于响应,但在 REST list 操作中,掩码则应用于返回资源列表中的每个单独消息。在 REST 自定义方法中,可能会使用其他定义。掩码的应用位置将在 API 声明中与掩码一起清楚地记录。在任何情况下,字段掩码对返回资源的影响都是 API 的必需行为。
更新操作中的字段掩码
更新操作中的字段掩码指定要更新目标资源的哪些字段。API 要求只更改掩码中指定的字段的值,而保持其他字段不变。如果传入资源来描述更新的值,API 将忽略掩码未涵盖的所有字段的值。
为了将字段的值重置为默认值,该字段必须在掩码中,并且在提供的资源中设置为默认值。因此,为了重置资源的所有字段,请提供资源的默认实例并在掩码中设置所有字段,或者按照下文所述不提供掩码。
如果更新时不存在字段掩码,则操作应用于所有字段(如同指定了所有字段的字段掩码)。请注意,在模式演进的情况下,这可能意味着客户端不知道因此未填充到请求中的字段将被重置为默认值。如果这是不希望的行为,特定服务可能要求客户端始终指定一个字段掩码,否则会产生错误。
与 get 操作一样,请求消息中描述更新值的资源位置取决于操作类型。在任何情况下,API 都必须遵循字段掩码的效果。
HTTP REST 考虑事项
使用字段掩码的更新操作的 HTTP 类型必须设置为 PATCH 而不是 PUT,以满足 HTTP 语义(PUT 仅用于完全更新)。
字段掩码的 JSON 编码
在 JSON 中,字段掩码编码为一个字符串,路径之间用逗号分隔。每个路径中的字段名称在小驼峰命名约定之间相互转换。
例如,考虑以下消息声明:
message Profile {
User user = 1;
Photo photo = 2;
}
message User {
string display_name = 1;
string address = 2;
}
在 proto 中,Profile
的字段掩码可能如下所示:
mask {
paths: "user.display_name"
paths: "photo"
}
在 JSON 中,相同的掩码表示如下:
{
mask: "user.displayName,photo"
}
字段名 | Type | 描述 |
---|---|---|
路径 | 字符串 | 字段掩码路径集。 |
FloatValue
float
的包装消息。
FloatValue
的 JSON 表示是 JSON 数字。
字段名 | Type | 描述 |
---|---|---|
值 | float | 浮点值。 |
Int32Value
int32
的包装消息。
Int32Value
的 JSON 表示是 JSON 数字。
字段名 | Type | 描述 |
---|---|---|
值 | int32 | int32 值。 |
Int64Value
int64
的包装消息。
Int64Value
的 JSON 表示是 JSON 字符串。
字段名 | Type | 描述 |
---|---|---|
值 | int64 | int64 值。 |
ListValue
ListValue
是值的 repeated 字段的包装器。
ListValue
的 JSON 表示是 JSON 数组。
字段名 | Type | 描述 |
---|---|---|
值 | Value | 动态类型值的 repeated 字段。 |
Method
Method 表示 api 的方法。
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 此方法的简单名称。 |
request_type_url | 字符串 | 输入消息类型的 URL。 |
request_streaming | bool | 如果为 true,则请求是流式的。 |
response_type_url | 字符串 | 输出消息类型的 URL。 |
response_streaming | bool | 如果为 true,则响应是流式的。 |
选项 | Option | 附加到方法的任何元数据。 |
语法 | Syntax | 此方法的源语法。 |
Mixin
声明一个 API 包含在此 API 中。包含的 API 必须重新声明被包含 API 的所有方法,但文档和选项按如下方式继承:
如果在移除注释和空白后,重新声明方法的文档字符串为空,则将从原始方法继承。
属于服务配置(http、visibility)的每个未在重新声明方法中设置的注解都将被继承。
如果继承了 http 注解,路径模式将按如下方式修改。任何版本前缀将被包含 API 的版本加上指定的
root
路径替换。
简单 Mixin 示例
package google.acl.v1;
service AccessControl {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v1/{resource=**}:getAcl";
}
}
package google.storage.v2;
service Storage {
// rpc GetAcl(GetAclRequest) returns (Acl);
// Get a data record.
rpc GetData(GetDataRequest) returns (Data) {
option (google.api.http).get = "/v2/{resource=**}";
}
}
Mixin 配置示例
apis:
- name: google.storage.v2.Storage
mixins:
- name: google.acl.v1.AccessControl
mixin 构造意味着 AccessControl
中的所有方法也在 Storage
中以相同的名称和请求/响应类型声明。文档生成器或注解处理器在继承文档和注解后将看到有效的 Storage.GetAcl
方法,如下所示:
service Storage {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v2/{resource=**}:getAcl";
}
...
}
注意路径模式中的版本如何从 v1
更改为 v2
。
如果指定了 mixin 中的 root
字段,则它应该是继承的 HTTP 路径放置的相对路径。示例:
apis:
- name: google.storage.v2.Storage
mixins:
- name: google.acl.v1.AccessControl
root: acls
这意味着以下继承的 HTTP 注解:
service Storage {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
}
...
}
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 被包含 API 的完全限定名称。 |
root | 字符串 | 如果非空,则指定继承的 HTTP 路径的根路径。 |
NullValue
NullValue
是一个单例枚举,表示 Value
类型联合的 null 值。
NullValue
的 JSON 表示是 JSON null
。
枚举值 | 描述 |
---|---|
NULL_VALUE | Null 值。 |
Option
一个 protocol buffer 选项,可以附加到消息、字段、枚举等。
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 选项的名称。例如,"java_package" 。 |
值 | Any | 选项的值。例如,"com.google.protobuf" 。 |
SourceContext
SourceContext
表示有关 protobuf 元素源的信息,例如定义它的文件。
字段名 | Type | 描述 |
---|---|---|
文件名 | 字符串 | 包含关联 protobuf 元素的 .proto 文件的路径限定名称。例如:"google/protobuf/source.proto" 。 |
StringValue
string
的包装消息。
StringValue
的 JSON 表示是 JSON 字符串。
字段名 | Type | 描述 |
---|---|---|
值 | 字符串 | 字符串值。 |
Struct
Struct
表示结构化数据值,由映射到动态类型值的字段组成。在某些语言中,Struct
可能由原生表示支持。例如,在 JS 等脚本语言中,struct 表示为一个对象。该表示的详细信息与该语言的 proto 支持一起描述。
Struct
的 JSON 表示是 JSON 对象。
字段名 | Type | 描述 |
---|---|---|
字段 | map<string, Value> | 动态类型值的映射。 |
Syntax
定义 protocol buffer 元素的语法。
枚举值 | 描述 |
---|---|
SYNTAX_PROTO2 | 语法 proto2 。 |
SYNTAX_PROTO3 | 语法 proto3 。 |
Timestamp
Timestamp 表示一个独立于任何时区或日历的时间点,以 UTC Epoch 时间的秒数和纳秒分辨率的秒分数表示。它使用倒推格里高利历进行编码,该日历将格里高利历向后扩展到元年。编码时假定所有分钟都为 60 秒长,即闰秒被“涂抹”,因此无需闰秒表即可解释。范围从 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59.999999999Z。通过限制在该范围内,我们确保可以与 RFC 3339 日期字符串相互转换。参见 https://www.ietf.org/rfc/rfc3339.txt。
Timestamp 类型以 RFC 3339 格式编码为字符串:“{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z
”,其中 {year}
始终使用四位数字表示,而 {month}
、{day}
、{hour}
、{min}
和 {sec}
都补零到两位数字。小数秒(最多可达 9 位数字,即分辨率高达 1 纳秒)是可选的。“Z”后缀表示时区(“UTC”);时区是必需的。proto3 JSON 序列化器在打印 Timestamp 类型时应始终使用 UTC(由“Z”表示),并且 proto3 JSON 解析器应能够接受 UTC 和其他时区(由偏移量表示)。
示例 1:从 POSIX time()
计算 Timestamp。
Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);
示例 2:从 POSIX gettimeofday()
计算 Timestamp。
struct timeval tv;
gettimeofday(&tv, NULL);
Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);
示例 3:从 Win32 GetSystemTimeAsFileTime()
计算 Timestamp。
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
Timestamp timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
示例 4:从 Java System.currentTimeMillis()
计算 Timestamp。
long millis = System.currentTimeMillis();
Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
.setNanos((int) ((millis % 1000) * 1000000)).build();
示例 5:从 Python 中的当前时间计算 Timestamp。
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
timestamp = Timestamp(seconds=seconds, nanos=nanos)
字段名 | Type | 描述 |
---|---|---|
秒 | int64 | 表示自 Unix Epoch 1970-01-01T00:00:00Z 以来的 UTC 时间秒数。必须在 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59Z(含)范围内。 |
纳秒 | int32 | 纳秒分辨率的非负秒分数。带有分数的负秒值仍必须具有非负的 nanos 值,这些值随着时间向前计数。必须在 0 到 999,999,999(含)范围内。 |
Type
一个 protocol buffer 消息类型。
字段名 | Type | 描述 |
---|---|---|
名称 | 字符串 | 消息的完全限定名称。 |
字段 | Field | 字段列表。 |
oneofs | 字符串 | 在此类型中出现在 oneof 定义中的类型列表。 |
选项 | Option | Protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
语法 | Syntax | 源语法。 |
UInt32Value
uint32
的包装消息。
UInt32Value
的 JSON 表示是 JSON 数字。
字段名 | Type | 描述 |
---|---|---|
值 | uint32 | uint32 值。 |
UInt64Value
uint64
的包装消息。
UInt64Value
的 JSON 表示是 JSON 字符串。
字段名 | Type | 描述 |
---|---|---|
值 | uint64 | uint64 值。 |
Value
Value
表示一个动态类型的值,可以是 null、数字、字符串、布尔值、递归结构体值或值列表。期望值的生产者设置其中一个变体,缺少任何变体表示错误。
Value
的 JSON 表示是 JSON value。
字段名 | Type | 描述 |
---|---|---|
联合字段,以下选项中只能选择一个: | ||
null_value | NullValue | 表示 null 值。 |
number_value | double | 表示 double 值。请注意,尝试序列化 NaN 或 Infinity 会导致错误。(我们无法将这些值序列化为字符串“NaN”或“Infinity”,就像我们对常规字段那样,因为它们会被解析为 string_value,而不是 number_value)。 |
string_value | 字符串 | 表示字符串值。 |
bool_value | bool | 表示布尔值。 |
struct_value | Struct | 表示结构化值。 |
list_value | ListValue | 表示 repeated Value 。 |