Protocol Buffers 知名類型

google.protobuf 套件的 API 文件。

索引

以「Value」結尾的知名類型是其他類型的包裝訊息,例如 BoolValueEnumValue。這些現在已過時。如今使用包裝函式的唯一理由是

  • 與已使用它們的訊息保持線路相容性。
  • 如果您想將純量值放入 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_urlstring

一個 URL/資源名稱,其內容描述序列化訊息的類型。

對於使用 schema httphttps 或無 schema 的 URL,適用以下限制和解釋

  • 如果未提供 schema,則假定為 https
  • URL 路徑的最後一段必須代表類型的完整名稱 (如 path/google.protobuf.Duration)。
  • 對 URL 執行 HTTP GET 必須產生二進位格式的 google.protobuf.Type 值,或產生錯誤。
  • 應用程式可以根據 URL 快取查詢結果,或將其預先編譯為二進位檔,以避免任何查詢。因此,在類型變更時需要保持二進位相容性。(使用版本化的類型名稱來管理重大變更。)

除了 httphttps (或空 schema) 之外的 Schema 可能會用於實作特定的語意。

valuebytes必須是上述指定類型的有效序列化資料。

Api

Api 是 Protocol Buffer 服務的輕量級描述符。

欄位名稱Type描述
namestring此 api 的完整名稱,包括套件名稱,後跟 api 的簡單名稱。
methodsMethod此 api 的方法,順序未指定。
optionsOption附加到 API 的任何元資料。
versionstring

此 api 的版本字串。如果指定,則必須採用 major-version.minor-version 格式,如 1.10。如果省略次要版本,則預設為零。如果整個版本欄位為空,則主要版本將從套件名稱衍生而來,如下所述。如果欄位不為空,則將驗證套件名稱中的版本是否與此處提供的版本一致。

版本控制 schema 使用語意化版本控制,其中主要版本號表示重大變更,而次要版本表示附加的非重大變更。這兩個版本號都是向使用者發出的訊號,表示他們可以從不同版本中獲得什麼,並且應該根據產品計畫仔細選擇。

主要版本也反映在 API 的套件名稱中,該名稱必須以 v<major-version> 結尾,如 google.feature.v1。對於主要版本 0 和 1,可以省略後綴。零主要版本只能用於實驗性的、非 GA api。

source_contextSourceContext此訊息所代表的 Protocol Buffer 服務的來源上下文。
mixinsMixin包含的 API。請參閱 Mixin
syntaxSyntax服務的來源語法。

BoolValue

bool 的包裝訊息。

BoolValue 的 JSON 表示法是 JSON truefalse

欄位名稱Type描述
valueboolbool 值。

BytesValue

bytes 的包裝訊息。

BytesValue 的 JSON 表示法是 JSON 字串。

欄位名稱Type描述
valuebytesbytes 值。

DoubleValue

double 的包裝訊息。

DoubleValue 的 JSON 表示法是 JSON 數字。

欄位名稱Type描述
valuedoubledouble 值。

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 結尾表示秒,前面是秒數,奈秒表示為秒的小數。

欄位名稱Type描述
secondsint64時間跨度的有號秒數。必須介於 -315,576,000,000 到 +315,576,000,000 之間,包括端點。
nanosint32時間跨度的奈秒解析度秒的小數的有號分數。小於一秒的 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描述
namestring列舉類型名稱。
enumvalueEnumValue列舉值定義。
optionsOptionProtocol Buffer 選項。
source_contextSourceContext來源上下文。
syntaxSyntax來源語法。

EnumValue

列舉值定義。

欄位名稱Type描述
namestring列舉值名稱。
numberint32列舉值編號。
optionsOptionProtocol Buffer 選項。

Field

訊息類型的單個欄位。

欄位名稱Type描述
kindKind欄位類型。
cardinalityCardinality欄位基數。
numberint32欄位編號。
namestring欄位名稱。
type_urlstring訊息或列舉類型的欄位類型 URL,不含 schema。範例:「type.googleapis.com/google.protobuf.Timestamp」。
oneof_indexint32訊息或列舉類型的欄位類型在 Type.oneofs 中的索引。第一個類型的索引為 1;零表示類型不在列表中。
packedbool是否使用替代的封裝線路表示法。
optionsOptionProtocol Buffer 選項。
json_namestring欄位 JSON 名稱。
default_valuestring此欄位預設值的字串值。僅限 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 代表某個根訊息中的欄位,ab 代表在 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 會忽略遮罩未涵蓋的所有欄位的值。

為了將欄位的值重設為預設值,該欄位必須在遮罩中,並在提供的資源中設定為預設值。因此,為了重設資源的所有欄位,請提供資源的預設實例,並在遮罩中設定所有欄位,或如下所述不提供遮罩。

如果在更新時不存在欄位遮罩,則該作業將套用於所有欄位 (如同已指定所有欄位的欄位遮罩)。請注意,在 schema 演進的情況下,這可能表示用戶端不知道且因此未填寫到請求中的欄位將會重設為其預設值。如果這是非預期的行為,則特定服務可能需要用戶端始終指定欄位遮罩,否則會產生錯誤。

與 get 作業一樣,描述請求訊息中更新值的資源位置取決於作業類型。在任何情況下,API 都必須遵守欄位遮罩的效果。

HTTP REST 的考量

使用欄位遮罩的更新作業的 HTTP 類型必須設定為 PATCH 而不是 PUT,以滿足 HTTP 語意 (PUT 只能用於完整更新)。

欄位遮罩的 JSON 編碼

在 JSON 中,欄位遮罩編碼為單個字串,其中路徑以逗號分隔。每個路徑中的欄位名稱都會轉換為/從 lower-camel 命名慣例轉換而來。

作為範例,請考慮以下訊息宣告

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描述
pathsstring欄位遮罩路徑的集合。

FloatValue

float 的包裝訊息。

FloatValue 的 JSON 表示法是 JSON 數字。

欄位名稱Type描述
valuefloatfloat 值。

Int32Value

int32 的包裝訊息。

Int32Value 的 JSON 表示法是 JSON 數字。

欄位名稱Type描述
valueint32int32 值。

Int64Value

int64 的包裝訊息。

Int64Value 的 JSON 表示法是 JSON 字串。

欄位名稱Type描述
valueint64int64 值。

ListValue

ListValue 是值重複欄位的包裝函式。

ListValue 的 JSON 表示法是 JSON 陣列。

欄位名稱Type描述
valuesValue動態類型值的重複欄位。

Method

Method 代表 api 的方法。

欄位名稱Type描述
namestring此方法的簡單名稱。
request_type_urlstring輸入訊息類型的 URL。
request_streamingbool如果為 true,則請求會串流。
response_type_urlstring輸出訊息類型的 URL。
response_streamingbool如果為 true,則回應會串流。
optionsOption附加到方法的任何元資料。
syntaxSyntax此方法的來源語法。

Mixin

宣告要包含在此 API 中的 API。包含的 API 必須重新宣告包含的 API 中的所有方法,但文件和選項會按如下方式繼承

  • 如果在註解和空白字元移除後,重新宣告方法的說明文件字串為空,則它將從原始方法繼承。

  • 屬於服務組態 (http、visibility) 且未在重新宣告方法中設定的每個註解都將被繼承。

  • 如果繼承了 http 註解,則路徑模式將按如下方式修改。任何版本前綴都將替換為包含 API 的版本加上指定的根路徑。

簡單 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描述
namestring包含的 API 的完整名稱。
rootstring如果非空,則指定繼承的 HTTP 路徑紮根在其下的路徑。

NullValue

NullValue 是一個單例列舉,用於表示 Value 類型聯集的 null 值。

NullValue 的 JSON 表示法是 JSON null

列舉值描述
NULL_VALUENull 值。

Option

一個 Protocol Buffer 選項,可以附加到訊息、欄位、列舉等。

欄位名稱Type描述
namestring選項的名稱。例如,「java_package」。
valueAny選項的值。例如,「com.google.protobuf」。

SourceContext

SourceContext 表示有關 protobuf 元素來源的資訊,例如定義它的檔案。

欄位名稱Type描述
file_namestring包含相關聯 protobuf 元素的 .proto 檔案的路徑限定名稱。例如:「google/protobuf/source.proto」。

StringValue

string 的包裝訊息。

StringValue 的 JSON 表示法是 JSON 字串。

欄位名稱Type描述
valuestringstring 值。

Struct

Struct 表示結構化資料值,由對應到動態類型值的欄位組成。在某些語言中,Struct 可能受到原生表示法的支援。例如,在 JS 等腳本語言中,struct 表示為物件。該表示法的詳細資訊與該語言的 proto 支援一起描述。

Struct 的 JSON 表示法是 JSON 物件。

欄位名稱Type描述
fieldsmap<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 位數字 (即最高奈秒解析度),是選填的。「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描述
secondsint64表示自 Unix epoch 1970-01-01T00:00:00Z 以來的 UTC 時間秒數。必須介於 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59Z 之間,包括端點。
nanosint32奈秒解析度的秒的非負分數。具有分數的負秒值仍必須具有向前計時的非負奈秒值。必須介於 0 到 999,999,999 之間,包括端點。

Type

Protocol Buffer 訊息類型。

欄位名稱Type描述
namestring訊息的完整名稱。
fieldsField欄位列表。
oneofsstring此類型中 oneof 定義中出現的類型列表。
optionsOptionProtocol Buffer 選項。
source_contextSourceContext來源上下文。
syntaxSyntax來源語法。

UInt32Value

uint32 的包裝訊息。

UInt32Value 的 JSON 表示法是 JSON 數字。

欄位名稱Type描述
valueuint32uint32 值。

UInt64Value

uint64 的包裝訊息。

UInt64Value 的 JSON 表示法是 JSON 字串。

欄位名稱Type描述
valueuint64uint64 值。

Value

Value 表示動態類型的值,可以是 null、數字、字串、布林值、遞迴 struct 值或值列表。Value 的產生器應設定其中一個變體,任何變體的缺失都表示錯誤。

Value 的 JSON 表示法是 JSON 值。

欄位名稱Type描述
聯集欄位,僅限以下其中一項
null_valueNullValue表示 null 值。
number_valuedouble表示 double 值。請注意,嘗試序列化 NaN 或 Infinity 會導致錯誤。(我們無法像對常規欄位那樣將這些序列化為字串「NaN」或「Infinity」值,因為它們會剖析為 string_value,而不是 number_value)。
string_valuestring表示 string 值。
bool_valuebool表示布林值。
struct_valueStruct表示結構化值。
list_valueListValue表示重複的 Value。