Protocol Buffers 知名类型
索引
Any(message)Api(message)BoolValue(message)BytesValue(message)DoubleValue(message)Duration(message)Empty(message)Enum(message)EnumValue(message)Field(message)Field.Cardinality(enum)Field.Kind(enum)FieldMask(message)FloatValue(message)Int32Value(message)Int64Value(message)ListValue(message)Method(message)Mixin(message)NullValue(enum)Option(message)SourceContext(message)StringValue(message)Struct(message)Syntax(enum)Timestamp(message)Type(message)UInt32Value(message)UInt64Value(message)Value(message)
以“Value”结尾的知名类型是其他类型的包装消息,例如 BoolValue 和 EnumValue。这些现在已过时。如今使用包装器的唯一原因可能是
- 与已经使用它们的消息进行线路兼容。
- 如果您想将标量值放入
Any消息中。
在大多数情况下,有更好的选择
- 对于新消息,最好使用常规的显式存在字段(proto2/proto3 中的
optional,版本 >= 2023 中的常规字段)。 - 扩展通常是比
Any字段更好的选择。
Any
Any 包含任意序列化的消息以及描述序列化消息类型的 URL。
JSON
Any 值的 JSON 表示使用反序列化的嵌入式消息的常规表示,并附加一个包含类型 URL 的字段 @type。示例
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 | string | 一个 URL/资源名称,其内容描述了序列化消息的类型。 对于使用
|
value | bytes | 必须是上述指定类型的有效序列化数据。 |
Api
Api 是 protocol buffer 服务的轻量级描述符。
| 字段名称 | Type | 描述 |
|---|---|---|
name | string | 此 api 的完全限定名称,包括包名和 api 的简单名称。 |
methods | Method | 此 api 的方法,顺序不确定。 |
options | 选项 | 附加到 API 的任何元数据。 |
version | string | 此 api 的版本字符串。如果指定,必须采用 版本控制方案使用 语义版本控制,其中主要版本号表示重大更改,次要版本表示附加的、非重大的更改。两个版本号都是向用户发出的信号,让他们知道不同版本的预期,应根据产品计划仔细选择。 主要版本也反映在 API 的包名中,该包名必须以 |
source_context | | 此消息所代表的 protocol buffer 服务的源上下文。 |
mixins | | 包含的 API。请参阅 Mixin。 |
syntax | 语法 | 服务的源语法。 |
BoolValue
bool 的包装消息。
BoolValue 的 JSON 表示是 JSON 的 true 和 false。
| 字段名称 | Type | 描述 |
|---|---|---|
value | bool | bool 值。 |
BytesValue
bytes 的包装消息。
BytesValue 的 JSON 表示是 JSON 字符串。
| 字段名称 | Type | 描述 |
|---|---|---|
value | bytes | bytes 值。 |
DoubleValue
double 的包装消息。
DoubleValue 的 JSON 表示是 JSON 数字。
| 字段名称 | Type | 描述 |
|---|---|---|
value | double | double 值。 |
Duration
Duration 表示一个有符号的、固定长度的时间跨度,表示为秒数和纳秒分辨率的秒数分数。它独立于任何日历和“天”或“月”等概念。它与 Timestamp 相关,因为两个 Timestamp 值之间的差异是一个 Duration,并且可以从 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 | string | 枚举类型名称。 |
enumvalue | EnumValue | 枚举值定义。 |
options | 选项 | Protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
syntax | 语法 | 源语法。 |
edition | string | 如果 syntax 是 SYNTAX_EDITIONS,则为源版本。 |
EnumValue
枚举值定义。
| 字段名称 | Type | 描述 |
|---|---|---|
name | string | 枚举值名称。 |
number | int32 | 枚举值编号。 |
options | 选项 | Protocol buffer 选项。 |
Field
消息类型的单个字段。
| 字段名称 | Type | 描述 |
|---|---|---|
kind | Kind | 字段类型。 |
cardinality | Cardinality | 字段基数。 |
number | int32 | 字段编号。 |
name | string | 字段名称。 |
type_url | string | 消息或枚举类型的字段类型 URL,不带协议。示例:"type.googleapis.com/google.protobuf.Timestamp"。 |
oneof_index | int32 | 对于消息或枚举类型,字段类型在 Type.oneofs 中的索引。第一个类型的索引为 1;零表示该类型不在列表中。 |
packed | bool | 是否使用替代的打包线路表示。 |
options | 选项 | Protocol buffer 选项。 |
json_name | string | 字段的 JSON 名称。 |
default_value | string | 此字段默认值的字符串值。仅限 Proto2 语法。 |
Cardinality
字段是可选、必需还是重复。
| 枚举值 | 描述 |
|---|---|
CARDINALITY_UNKNOWN | 对于基数未知的字段。 |
CARDINALITY_OPTIONAL | 对于可选字段。 |
CARDINALITY_REQUIRED | 对于必需字段。仅限 Proto2 语法。 |
CARDINALITY_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 操作应返回的字段子集(投影),或由 update 操作修改的字段子集。字段掩码还具有自定义的 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
}
}
不允许重复字段,除非在字段掩码的最后一个位置。
如果 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 | 描述 |
|---|---|---|
paths | string | 字段掩码路径的集合。 |
FloatValue
float 的包装消息。
FloatValue 的 JSON 表示是 JSON 数字。
| 字段名称 | Type | 描述 |
|---|---|---|
value | float | float 值。 |
Int32Value
int32 的包装消息。
Int32Value 的 JSON 表示是 JSON 数字。
| 字段名称 | Type | 描述 |
|---|---|---|
value | int32 | int32 值。 |
Int64Value
int64 的包装消息。
Int64Value 的 JSON 表示是 JSON 字符串。
| 字段名称 | Type | 描述 |
|---|---|---|
value | int64 | int64 值。 |
ListValue
ListValue 是一个围绕重复值字段的包装器。
ListValue 的 JSON 表示是 JSON 数组。
| 字段名称 | Type | 描述 |
|---|---|---|
values | Value | 动态类型值的重复字段。 |
Method
Method 表示 api 的一个方法。
| 字段名称 | Type | 描述 |
|---|---|---|
name | string | 此方法的简单名称。 |
request_type_url | string | 输入消息类型的 URL。 |
request_streaming | bool | 如果为 true,则请求是流式的。 |
response_type_url | string | 输出消息类型的 URL。 |
response_streaming | bool | 如果为 true,则响应是流式的。 |
options | 选项 | 附加到方法的任何元数据。 |
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 | 描述 |
|---|---|---|
name | string | 被包含的 API 的完全限定名称。 |
root | string | 如果非空,则指定一个路径,继承的 HTTP 路径将以此为根。 |
NullValue
NullValue 是一个单例枚举,用于表示 Value 类型联合的空值。
NullValue 的 JSON 表示是 JSON null。
| 枚举值 | 描述 |
|---|---|
NULL_VALUE | 空值。 |
选项
一个 protocol buffer 选项,可以附加到消息、字段、枚举等。
| 字段名称 | Type | 描述 |
|---|---|---|
name | string | 选项的名称。例如,"java_package"。 |
value | Any | 选项的值。例如,"com.google.protobuf"。 |
SourceContext
SourceContext 表示有关 protobuf 元素源的信息,例如它在其中定义的文件。
| 字段名称 | Type | 描述 |
|---|---|---|
file_name | string | 包含关联 protobuf 元素的 .proto 文件的路径限定名称。例如:"google/protobuf/source.proto"。 |
StringValue
string 的包装消息。
StringValue 的 JSON 表示是 JSON 字符串。
| 字段名称 | Type | 描述 |
|---|---|---|
value | string | 字符串值。 |
Struct
Struct 表示一个结构化的数据值,由映射到动态类型值的字段组成。在某些语言中,Struct 可能由本机表示支持。例如,在像 JS 这样的脚本语言中,结构体表示为一个对象。该表示的详细信息与该语言的 proto 支持一起描述。
Struct 的 JSON 表示是 JSON 对象。
| 字段名称 | Type | 描述 |
|---|---|---|
fields | map<string, Value> | 动态类型值的映射。 |
语法
定义 protocol buffer 元素的语法。
| 枚举值 | 描述 |
|---|---|
SYNTAX_PROTO2 | 语法 proto2。 |
SYNTAX_PROTO3 | 语法 proto3。 |
SYNTAX_EDITIONS | 语法使用 edition 构造。 |
Timestamp
Timestamp 表示一个与任何时区或日历无关的时间点,表示为自 UTC 纪元以来的秒数和纳秒分辨率的秒数分数。它使用 Proleptic Gregorian Calendar(将公历向后延伸至公元一年)进行编码。它的编码假设所有分钟都是 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 | 描述 |
|---|---|---|
seconds | int64 | 表示自 Unix 纪元 1970-01-01T00:00:00Z 以来的 UTC 时间秒数。必须在 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59Z 之间(含)。 |
nanos | int32 | 纳秒分辨率的非负秒数分数。带有分数的负秒值仍必须具有随时间向前计数的非负 nanos 值。必须在 0 到 999,999,999 之间(含)。 |
Type
一个 protocol buffer 消息类型。
| 字段名称 | Type | 描述 |
|---|---|---|
name | string | 完全限定的消息名称。 |
fields | Field | 字段列表。 |
oneofs | string | 此类型中出现在 oneof 定义中的类型列表。 |
options | 选项 | Protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
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 | 表示一个 double 值。请注意,尝试序列化 NaN 或 Infinity 会导致错误。(我们不能像处理常规字段那样将它们序列化为字符串 "NaN" 或 "Infinity",因为它们会被解析为 string_value,而不是 number_value)。 |
string_value | string | 表示一个字符串值。 |
bool_value | bool | 表示一个布尔值。 |
struct_value | Struct | 表示一个结构化值。 |
list_value | ListValue | 表示一个重复的 Value。 |