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 | 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 | 布林值。 |
BytesValue
bytes 的包裝訊息。
BytesValue 的 JSON 表示是 JSON 字串。
| 欄位名 | Type | 描述 |
|---|---|---|
value | bytes | 位元組值。 |
DoubleValue
double 的包裝訊息。
DoubleValue 的 JSON 表示是 JSON 數字。
| 欄位名 | Type | 描述 |
|---|---|---|
value | 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 | 時間跨度的納秒解析度的帶符號秒分數。小於一秒的 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 | 描述 |
|---|---|---|
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 | 是否使用替代的 packed 有線表示。 |
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 中找到的訊息中的欄位。
欄位掩碼用於指定應由獲取操作返回(一個 _投影_)或由更新操作修改的欄位子集。欄位掩碼也有自定義的 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 | 描述 |
|---|---|---|
paths | string | 欄位掩碼路徑集。 |
FloatValue
float 的包裝訊息。
FloatValue 的 JSON 表示是 JSON 數字。
| 欄位名 | Type | 描述 |
|---|---|---|
value | 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、可見性)的每個未在重新宣告方法中設定的註解都將繼承。
如果繼承了 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 表示關於 Protocol Buffer 元素源的資訊,例如它定義在哪個檔案中。
| 欄位名 | Type | 描述 |
|---|---|---|
file_name | string | 包含關聯 Protocol Buffer 元素的 .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 位,即納秒解析度)是可選的。“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 | 納秒解析度的非負小數秒。帶有小數的負秒值仍必須具有向前計時的非負納秒值。必須在 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 | 表示一個雙精度值。請注意,嘗試序列化 NaN 或 Infinity 會導致錯誤。(我們不能像處理常規欄位那樣將它們序列化為字串“NaN”或“Infinity”,因為它們會被解析為 string_value,而不是 number_value)。 |
string_value | string | 表示一個字串值。 |
bool_value | bool | 表示一個布林值。 |
struct_value | Struct | 表示一個結構化值。 |
list_value | ListValue | 表示一個重複的 Value。 |