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
,在版本 >= 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/资源名称,其内容描述了序列化消息的类型。 对于使用
除了 |
value | 字节 | 必须是上述指定类型的有效序列化数据。 |
Api
Api 是协议缓冲区服务的轻量级描述符。
字段名称 | Type | 描述 |
---|---|---|
name | 字符串 | 此 api 的完全限定名称,包括包名称后跟 api 的简单名称。 |
methods | Method | 此 api 的方法,顺序未指定。 |
options | Option | 附加到 API 的任何元数据。 |
version | 字符串 | 此 api 的版本字符串。如果指定,必须采用 版本方案使用 语义版本控制,其中主要版本号表示重大更改,次要版本表示附加的非重大更改。这两个版本号都是向用户发出信号,让他们了解不同版本中的预期内容,并且应根据产品计划仔细选择。 主要版本也反映在 API 的包名称中,包名称必须以 |
source_context |
| 此消息表示的协议缓冲区服务的源上下文。 |
mixins |
| 包含的 API。参见 Mixin 。 |
syntax | Syntax | 服务的源语法。 |
BoolValue
bool
的包装消息。
BoolValue
的 JSON 表示形式为 JSON true
和 false
。
字段名称 | Type | 描述 |
---|---|---|
value | bool | 布尔值。 |
BytesValue
bytes
的包装消息。
BytesValue
的 JSON 表示形式为 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | 字节 | 字节值。 |
DoubleValue
double
的包装消息。
DoubleValue
的 JSON 表示形式为 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | double | 双精度值。 |
Duration
Duration 表示一个带符号的、固定长度的时间跨度,表示为以纳秒分辨率计的秒数和小数秒数。它独立于任何日历和诸如“天”或“月”之类的概念。它与 Timestamp 相关,因为两个 Timestamp 值之间的差值是 Duration,并且可以将其加到 Timestamp 或从 Timestamp 中减去。范围大约为 +/- 10,000 年。
示例 1:在伪代码中计算两个 Timestamp 之间的 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 | 描述 |
---|---|---|
seconds | int64 | 时间跨度的带符号秒数。必须在 -315,576,000,000 到 +315,576,000,000(含)之间。 |
nanos | int32 | 时间跨度的纳秒分辨率带符号小数秒。小于一秒的持续时间用 0 seconds 字段和正或负 nanos 字段表示。对于持续时间为一秒或更长的时间,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 | 描述 |
---|---|---|
name | 字符串 | 枚举类型名称。 |
enumvalue | EnumValue | 枚举值定义。 |
options | Option | 协议缓冲区选项。 |
source_context | SourceContext | 源上下文。 |
syntax | Syntax | 源语法。 |
EnumValue
枚举值定义。
字段名称 | Type | 描述 |
---|---|---|
name | 字符串 | 枚举值名称。 |
数字 | int32 | 枚举值编号。 |
options | Option | 协议缓冲区选项。 |
Field
消息类型的一个字段。
字段名称 | Type | 描述 |
---|---|---|
类型 | Kind | 字段类型。 |
基数 | Cardinality | 字段基数。 |
数字 | int32 | 字段编号。 |
name | 字符串 | 字段名称。 |
type_url | 字符串 | 字段类型 URL,不包含方案,用于消息或枚举类型。例如:"type.googleapis.com/google.protobuf.Timestamp" 。 |
oneof_index | int32 | 字段类型在 Type.oneofs 中的索引,用于消息或枚举类型。第一个类型索引为 1;零表示该类型不在列表中。 |
packed | bool | 是否使用备用打包线格式。 |
options | Option | 协议缓冲区选项。 |
json_name | 字符串 | 字段 JSON 名称。 |
default_value | 字符串 | 此字段默认值的字符串值。仅限 Proto2 语法。 |
Cardinality
字段是可选、必填还是重复的。
枚举值 | 描述 |
---|---|
CARDINALITY_UNKNOWN | 用于基数未知的字段。 |
CARDINALITY_OPTIONAL | 用于可选字段。 |
CARDINALITY_REQUIRED | 用于必填字段。仅限 Proto2 语法。 |
CARDINALITY_REPEATED | 用于重复字段。 |
Kind
基本字段类型。
枚举值 | 描述 |
---|---|
TYPE_UNKNOWN | 字段类型未知。 |
TYPE_DOUBLE | 字段类型双精度。 |
TYPE_FLOAT | 字段类型浮点。 |
TYPE_INT64 | 字段类型 int64。 |
TYPE_UINT64 | 字段类型 uint64。 |
TYPE_INT32 | 字段类型 int32。 |
TYPE_FIXED64 | 字段类型 fixed64。 |
TYPE_FIXED32 | 字段类型 fixed32。 |
TYPE_BOOL | 字段类型布尔。 |
TYPE_STRING | 字段类型字符串。 |
TYPE_GROUP | 字段类型组。仅限 Proto2 语法,且已弃用。 |
TYPE_MESSAGE | 字段类型消息。 |
TYPE_BYTES | 字段类型字节。 |
TYPE_UINT32 | 字段类型 uint32。 |
TYPE_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
中的消息中找到的字段。
字段掩码用于指定获取操作(投影)应返回的字段子集,或更新操作应修改的字段子集。字段掩码还具有自定义 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
}
}
重复字段不允许出现在字段掩码的最后一个位置以外。
如果获取操作中不存在 FieldMask
对象,则该操作将应用于所有字段(就像指定了所有字段的 FieldMask 一样)。
请注意,字段掩码不一定应用于顶级响应消息。在 REST 获取操作的情况下,字段掩码直接应用于响应,但在 REST 列表操作的情况下,掩码则应用于返回的资源列表中的每个单独消息。在 REST 自定义方法的情况下,可能会使用其他定义。掩码应用的位置将在 API 的声明中与之一起明确记录。无论如何,对返回的资源/资源的影响都是 API 的必需行为。
更新操作中的字段掩码
更新操作中的字段掩码指定将更新目标资源的哪些字段。API 必须仅更改掩码中指定的字段的值,并将其他字段保持不变。如果传入资源来描述更新的值,则 API 会忽略掩码未涵盖的所有字段的值。
为了将字段的值重置为默认值,该字段必须位于掩码中,并在提供的资源中设置为默认值。因此,为了重置资源的所有字段,请提供资源的默认实例并在掩码中设置所有字段,或者不提供掩码,如下所述。
如果更新时不存在字段掩码,则该操作将应用于所有字段(就像指定了所有字段的字段掩码一样)。请注意,在存在模式演变的情况下,这可能意味着客户端不知道且因此未填写到请求中的字段将重置为其默认值。如果这是不希望的行为,则特定服务可能要求客户端始终指定字段掩码,如果未指定则产生错误。
与获取操作一样,请求消息中描述更新值的资源位置取决于操作类型。无论如何,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 | 描述 |
---|---|---|
value | 浮点数 | 浮点值。 |
Int32Value
int32
的包装消息。
Int32Value
的 JSON 表示形式为 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | int32 | int32 值。 |
Int64Value
int64
的包装消息。
Int64Value
的 JSON 表示形式为 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | int64 | int64 值。 |
ListValue
ListValue
是围绕值的重复字段的包装器。
ListValue
的 JSON 表示形式为 JSON 数组。
字段名称 | Type | 描述 |
---|---|---|
值 | Value | 动态类型值的重复字段。 |
Method
Method 表示 API 的方法。
字段名称 | Type | 描述 |
---|---|---|
name | 字符串 | 此方法的简单名称。 |
request_type_url | 字符串 | 输入消息类型的 URL。 |
request_streaming | bool | 如果为真,则请求是流式传输的。 |
response_type_url | 字符串 | 输出消息类型的 URL。 |
response_streaming | bool | 如果为真,则响应是流式传输的。 |
options | Option | 附加到方法的任何元数据。 |
syntax | Syntax | 此方法的源语法。 |
Mixin
声明要包含在此 API 中的 API。包含的 API 必须重新声明包含的 API 中的所有方法,但文档和选项按如下方式继承
如果在注释和空格剥离后,重新声明的方法的文档字符串为空,则它将从原始方法继承。
属于服务配置(http、可见性)的每个未在重新声明的方法中设置的注释都将被继承。
如果继承了 http 注释,则路径模式将按如下方式修改。任何版本前缀都将替换为包含 API 的版本以及指定的
root
路径。
简单混合的示例
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=**}";
}
}
混合配置示例
apis:
- name: google.storage.v2.Storage
mixins:
- name: google.acl.v1.AccessControl
混合结构意味着 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
。
如果在混合中指定了 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 | 描述 |
---|---|---|
name | 字符串 | 包含的 API 的完全限定名称。 |
root | 字符串 | 如果非空,则指定继承的 HTTP 路径所在的路径。 |
NullValue
NullValue
是一个单例枚举,用于表示 Value
类型联合的空值。
NullValue
的 JSON 表示形式为 JSON null
。
枚举值 | 描述 |
---|---|
NULL_VALUE | 空值。 |
Option
协议缓冲区选项,可以附加到消息、字段、枚举等。
字段名称 | Type | 描述 |
---|---|---|
name | 字符串 | 选项的名称。例如,"java_package" 。 |
value | Any | 选项的值。例如,"com.google.protobuf" 。 |
SourceContext
SourceContext
表示有关 protobuf 元素来源的信息,例如定义它的文件。
字段名称 | Type | 描述 |
---|---|---|
file_name | 字符串 | 包含关联的 protobuf 元素的 .proto 文件的路径限定名称。例如:"google/protobuf/source.proto" 。 |
StringValue
string
的包装消息。
StringValue
的 JSON 表示形式为 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | 字符串 | 字符串值。 |
Struct
Struct
表示结构化数据值,由映射到动态类型值的字段组成。在某些语言中,Struct
可能受本机表示支持。例如,在 JS 等脚本语言中,结构表示为对象。该表示的详细信息与该语言的 proto 支持一起描述。
Struct
的 JSON 表示形式为 JSON 对象。
字段名称 | Type | 描述 |
---|---|---|
字段 | map<string, Value> | 动态类型值的映射。 |
Syntax
定义协议缓冲区元素的语法。
枚举值 | 描述 |
---|---|
SYNTAX_PROTO2 | 语法 proto2 。 |
SYNTAX_PROTO3 | 语法 proto3 。 |
Timestamp
Timestamp 表示与任何时区或日历无关的时间点,以纳秒分辨率的秒和秒的分数表示为 UTC 纪元时间。它使用前摄格里高利历进行编码,该历将格里高利历向后扩展到公元一年。它假设所有分钟都是 60 秒长进行编码,即闰秒被“涂抹”,因此不需要闰秒表进行解释。范围从 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59.999999999Z。通过限制该范围,我们确保可以转换为和从 RFC 3339 日期字符串转换。请参见 https://www.ietf.org/rfc/rfc3339.txt。
示例 1:从 POSIX time()
计算时间戳。
Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);
示例 2:从 POSIX gettimeofday()
计算时间戳。
struct timeval tv;
gettimeofday(&tv, NULL);
Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);
示例 3:从 Win32 GetSystemTimeAsFileTime()
计算时间戳。
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()
计算时间戳。
long millis = System.currentTimeMillis();
Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
.setNanos((int) ((millis % 1000) * 1000000)).build();
示例 5:从 Python 中的当前时间计算时间戳。
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
timestamp = Timestamp(seconds=seconds, nanos=nanos)
字段名称 | Type | 描述 |
---|---|---|
seconds | int64 | 表示自 Unix 纪元 1970-01-01T00:00:00Z 以来 UTC 时间的秒数。必须在 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59Z(含)之间。 |
nanos | int32 | 以纳秒分辨率表示的非负秒分数。带分数的负秒值仍必须具有非负纳秒值,这些值随时间推移向前计数。必须在 0 到 999,999,999(含)之间。 |
Type
协议缓冲区消息类型。
字段名称 | Type | 描述 |
---|---|---|
name | 字符串 | 完全限定的消息名称。 |
字段 | Field | 字段列表。 |
oneofs | 字符串 | 此类型中 oneof 定义中出现的类型列表。 |
options | Option | 协议缓冲区选项。 |
source_context | SourceContext | 源上下文。 |
syntax | Syntax | 源语法。 |
UInt32Value
uint32
的包装消息。
UInt32Value
的 JSON 表示形式为 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | uint32 | uint32 值。 |
UInt64Value
uint64
的包装消息。
UInt64Value
的 JSON 表示形式为 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | uint64 | uint64 值。 |
Value
Value
表示一个动态类型的值,可以是 null、数字、字符串、布尔值、递归结构体值或值的列表。预期值生产者会设置其中一个变体,任何变体都不存在则表示错误。
Value
的 JSON 表示形式为 JSON 值。
字段名称 | Type | 描述 |
---|---|---|
联合字段,以下选项仅有一个有效 | ||
null_value | NullValue | 表示空值。 |
number_value | double | 表示双精度浮点数。请注意,尝试序列化 NaN 或 Infinity 会导致错误。(我们不能像序列化常规字段那样将它们序列化为字符串 "NaN" 或 "Infinity",因为它们会被解析为 string_value,而不是 number_value)。 |
string_value | 字符串 | 表示字符串值。 |
bool_value | bool | 表示布尔值。 |
struct_value | Struct | 表示结构化值。 |
list_value | ListValue | 表示重复的 Value 。 |