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 表示法使用還原序列化、嵌入訊息的常規表示法,以及包含類型 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 | 字串 | 一個 URL/資源名稱,其內容描述序列化訊息的類型。 對於使用 schema
除 |
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
持續時間表示有符號、固定長度的時間跨度,表示為秒數和奈秒解析度的秒數分數。它獨立於任何日曆和「天」或「月」等概念。它與時間戳相關,因為兩個時間戳值之間的差異是一個持續時間,並且可以從時間戳中添加或減去持續時間。範圍約為 +-10,000 年。
範例 1:在偽代碼中從兩個時間戳計算持續時間。
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 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 | Protocol buffer 選項。 |
source_context | SourceContext | 來源上下文。 |
syntax | Syntax | 來源語法。 |
EnumValue
列舉值定義。
欄位名稱 | Type | 描述 |
---|---|---|
name | 字串 | 列舉值名稱。 |
number | int32 | 列舉值數字。 |
options | Option | Protocol buffer 選項。 |
Field
訊息類型中的單一欄位。
欄位名稱 | Type | 描述 |
---|---|---|
kind | Kind | 欄位類型。 |
cardinality | Cardinality | 欄位基數。 |
number | int32 | 欄位號碼。 |
name | 字串 | 欄位名稱。 |
type_url | 字串 | 訊息或列舉類型的欄位類型 URL,不含協定。範例:"type.googleapis.com/google.protobuf.Timestamp" 。 |
oneof_index | int32 | 訊息或列舉類型的欄位類型在 Type.oneofs 中的索引。第一個類型的索引為 1;零表示類型不在列表中。 |
packed | bool | 是否使用替代的封裝連線表示法。 |
options | Option | Protocol buffer 選項。 |
json_name | 字串 | 欄位的 JSON 名稱。 |
default_value | 字串 | 此欄位預設值的字串值。僅限 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 操作傳回(一個投影),或由更新操作修改。欄位遮罩也有一個自訂的 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 | 字串 | 欄位遮罩路徑的集合。 |
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 | 字串 | 此方法的簡單名稱。 |
request_type_url | 字串 | 輸入訊息類型的 URL。 |
request_streaming | bool | 如果為 true,則請求會串流。 |
response_type_url | 字串 | 輸出訊息類型的 URL。 |
response_streaming | bool | 如果為 true,則回應會串流。 |
options | Option | 附加到方法的所有中繼資料。 |
syntax | 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 | 字串 | 包含的 API 的完整名稱。 |
root | 字串 | 如果非空,則指定繼承 HTTP 路徑所植根的路徑。 |
NullValue
NullValue
是一個單例列舉,用於表示 Value
類型聯集的 null 值。
NullValue
的 JSON 表示法為 JSON null
。
列舉值 | 描述 |
---|---|
NULL_VALUE | Null 值。 |
Option
一個 protocol buffer 選項,可以附加到訊息、欄位、列舉等。
欄位名稱 | 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 | 字串 | string 值。 |
Struct
Struct
表示結構化資料值,包含對應至動態類型值的欄位。在某些語言中,原生表示法可能會支援 Struct
。例如,在 JS 等指令碼語言中,結構表示為物件。該表示法的詳細資訊與語言的 proto 支援一起描述。
Struct
的 JSON 表示法為 JSON 物件。
欄位名稱 | Type | 描述 |
---|---|---|
fields | map<string, Value> | 動態類型值的對應。 |
Syntax
定義 protocol buffer 元素的語法。
列舉值 | 描述 |
---|---|
SYNTAX_PROTO2 | 語法 proto2 。 |
SYNTAX_PROTO3 | 語法 proto3 。 |
Timestamp
Timestamp 代表時間上的某一點,它獨立於任何時區或日曆,表示為自 UTC Epoch 時間起算的秒數和分數秒數(奈秒解析度)。它使用 Proleptic Gregorian Calendar 進行編碼,該日曆將 Gregorian Calendar 向後延伸到第一年。它的編碼假設所有分鐘都是 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;
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 epoch 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 | 字串 | 完整訊息名稱。 |
fields | Field | 欄位列表。 |
oneofs | 字串 | 此類型中 oneof 定義中出現的類型列表。 |
options | Option | Protocol buffer 選項。 |
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 | 表示一個 null 值。 |
number_value | double | 表示一個雙精度浮點數值。請注意,嘗試序列化 NaN 或 Infinity 會導致錯誤。(我們不能像處理一般欄位那樣將它們序列化為字串 "NaN" 或 "Infinity" 值,因為它們會被解析為 string_value,而不是 number_value)。 |
string_value | 字串 | 表示一個字串值。 |
bool_value | bool | 表示一個布林值。 |
struct_value | Struct | 表示一個結構化值。 |
list_value | ListValue | 表示重複的 Value 。 |