Protocol Buffers 知名型別

google.protobuf 包的 API 文件。

索引

以“Value”結尾的知名型別是其他型別的包裝訊息,例如 BoolValueEnumValue。這些現在已廢棄。如今使用包裝器的唯一原因是

  • 與已使用它們的舊訊息進行有線相容。
  • 如果你想將標量值放入 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_urlstring

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

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

  • 如果未提供模式,則假定為 https
  • URL 路徑的最後一段必須表示型別的完全限定名(如 path/google.protobuf.Duration)。
  • 對 URL 執行 HTTP GET 必須以二進位制格式返回一個 google.protobuf.Type 值,否則會產生錯誤。
  • 應用程式可以根據 URL 快取查詢結果,或者將其預編譯到二進位制檔案中以避免任何查詢。因此,型別更改時需要保持二進位制相容性。(使用版本化型別名稱來管理破壞性更改。)

除了 httphttps(或空模式)之外的模式可以與實現特定的語義一起使用。

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

Api

Api 是一個用於 Protocol Buffer 服務的輕量級描述符。

欄位名Type描述
namestring此 API 的完全限定名稱,包括包名,後跟 API 的簡單名稱。
methodsMethod此 API 的方法,順序未指定。
options選項附加到 API 的任何元資料。
versionstring

此 API 的版本字串。如果指定,必須採用 major-version.minor-version 的形式,例如 1.10。如果省略次版本號,則預設為零。如果整個版本欄位為空,則主版本號從包名中派生,如下所述。如果該欄位不為空,則將驗證包名中的版本與此處提供的版本是否一致。

版本控制方案使用 語義版本控制,其中主版本號表示破壞性更改,次版本號表示增量、非破壞性更改。兩個版本號都是向用戶發出的訊號,說明不同版本的預期,應根據產品計劃仔細選擇。

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

source_contextSourceContext此訊息表示的 Protocol Buffer 服務的源上下文。
mixinsMixin包含的 API。參見 Mixin
syntax語法服務的源語法。

BoolValue

bool 的包裝訊息。

BoolValue 的 JSON 表示是 JSON truefalse

欄位名Type描述
valuebool布林值。

BytesValue

bytes 的包裝訊息。

BytesValue 的 JSON 表示是 JSON 字串。

欄位名Type描述
valuebytes位元組值。

DoubleValue

double 的包裝訊息。

DoubleValue 的 JSON 表示是 JSON 數字。

欄位名Type描述
valuedouble雙精度值。

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描述
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列舉值定義。
options選項Protocol Buffer 選項。
source_contextSourceContext源上下文。
syntax語法源語法。
editionstring如果 syntaxSYNTAX_EDITIONS,則為源版本。

EnumValue

列舉值定義。

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

Field

訊息型別的一個欄位。

欄位名Type描述
kindKind欄位型別。
cardinalityCardinality欄位基數。
numberint32欄位編號。
namestring欄位名稱。
type_urlstring訊息或列舉型別的欄位型別 URL,不帶方案。示例:"type.googleapis.com/google.protobuf.Timestamp"
oneof_indexint32對於訊息或列舉型別,該欄位型別在 Type.oneofs 中的索引。第一個型別索引為 1;零表示該型別不在列表中。
packedbool是否使用替代的 packed 有線表示。
options選項Protocol 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 中找到的訊息中的欄位。

欄位掩碼用於指定應由獲取操作返回(一個 _投影_)或由更新操作修改的欄位子集。欄位掩碼也有自定義的 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描述
pathsstring欄位掩碼路徑集。

FloatValue

float 的包裝訊息。

FloatValue 的 JSON 表示是 JSON 數字。

欄位名Type描述
valuefloat浮點值。

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,則響應是流式的。
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描述
namestring包含的 API 的完全限定名。
rootstring如果非空,則指定繼承的 HTTP 路徑的根路徑。

NullValue

NullValue 是一個單例列舉,表示 Value 型別聯合的空值。

NullValue 的 JSON 表示是 JSON null

列舉值描述
NULL_VALUE空值。

選項

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

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

SourceContext

SourceContext 表示關於 Protocol Buffer 元素源的資訊,例如它定義在哪個檔案中。

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

StringValue

string 的包裝訊息。

StringValue 的 JSON 表示是 JSON 字串。

欄位名Type描述
valuestring字串值。

Struct

Struct 表示一個結構化資料值,由對映到動態型別值的欄位組成。在某些語言中,Struct 可能由原生表示支援。例如,在 JS 等指令碼語言中,結構體表示為物件。該表示的詳細資訊與該語言的 proto 支援一起描述。

Struct 的 JSON 表示是 JSON 物件。

欄位名Type描述
fieldsmap<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描述
secondsint64自 Unix 紀元 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 定義中的型別列表。
options選項Protocol Buffer 選項。
source_contextSourceContext源上下文。
syntax語法源語法。

UInt32Value

uint32 的包裝訊息。

UInt32Value 的 JSON 表示是 JSON 數字。

欄位名Type描述
valueuint32uint32 值。

UInt64Value

uint64 的包裝訊息。

UInt64Value 的 JSON 表示是 JSON 字串。

欄位名Type描述
valueuint64uint64 值。

Value

Value 表示一個動態型別的值,可以是 null、數字、字串、布林值、遞迴結構體值或值列表。值的生成者應設定其中一種變體,缺少任何變體表示錯誤。

Value 的 JSON 表示是 JSON 值。

欄位名Type描述
聯合欄位,以下只有一個
null_valueNullValue表示一個空值。
number_valuedouble表示一個雙精度值。請注意,嘗試序列化 NaN 或 Infinity 會導致錯誤。(我們不能像處理常規欄位那樣將它們序列化為字串“NaN”或“Infinity”,因為它們會被解析為 string_value,而不是 number_value)。
string_valuestring表示一個字串值。
bool_valuebool表示一個布林值。
struct_valueStruct表示一個結構化值。
list_valueListValue表示一個重複的 Value