ProtoJSON 格式
Protobuf 支援 JSON 中的標準編碼,使其更容易與不支援標準 protobuf 二進位線格式的系統共享資料。
ProtoJSON 格式不如 protobuf 線格式有效率。轉換器使用更多 CPU 來編碼和解碼訊息,並且(除了少數情況外)編碼的訊息佔用更多空間。此外,ProtoJSON 格式會將您的欄位和列舉值名稱放入編碼的訊息中,這使得稍後變更這些名稱變得更加困難。移除欄位是一個重大變更,會觸發剖析錯誤。簡而言之,有很多充分的理由讓 Google 偏好使用標準線格式來處理幾乎所有事情,而不是使用 ProtoJSON 格式。
編碼會在稍後此主題的表格中依類型進行描述。
將 JSON 編碼的資料剖析到協定緩衝區時,如果值遺失或其值為 null
,則會將其解譯為對應的預設值。
從協定緩衝區產生 JSON 編碼的輸出時,如果 protobuf 欄位具有預設值,且該欄位不支援欄位存在,則預設會從輸出中省略該欄位。實作可能會提供選項,以在輸出中包含具有預設值的欄位。
設定了值且支援欄位存在的欄位,在 JSON 編碼的輸出中一律會包含欄位值,即使它是預設值。例如,以 optional
關鍵字定義的 proto3 欄位支援欄位存在,如果已設定,則一律會出現在 JSON 輸出中。任何版本的 protobuf 中的訊息類型欄位都支援欄位存在,如果已設定,則會出現在輸出中。Proto3 隱含存在純量欄位只有在未設定為該類型的預設值時,才會出現在 JSON 輸出中。
Protobuf | JSON | JSON 範例 | 注意事項 |
---|---|---|---|
message (訊息) | object (物件) | {"fooBar": v, "g": null, ...} | 產生 JSON 物件。訊息欄位名稱會對應到 lowerCamelCase,並成為 JSON 物件索引鍵。如果指定了 json_name 欄位選項,則會改為使用指定的值作為索引鍵。剖析器會接受 lowerCamelCase 名稱(或 json_name 選項指定的名稱)和原始 proto 欄位名稱。null 是所有欄位類型接受的值,並視為對應欄位類型的預設值。但是,null 不能用於 json_name 值。如需更多相關資訊,請參閱 json_name 的更嚴格驗證。 |
enum (列舉) | string (字串) | "FOO_BAR" | 使用 proto 中指定的列舉值名稱。剖析器接受列舉名稱和整數值。 |
map<K,V> | object (物件) | {"k": v, ...} | 所有索引鍵都會轉換為字串。 |
repeated V | array (陣列) | [v, ...] | null 會被接受為空清單 [] 。 |
bool (布林值) | true, false | true, false | |
string (字串) | string (字串) | "Hello World!" | |
bytes (位元組) | base64 字串 | "YWJjMTIzIT8kKiYoKSctPUB+" | JSON 值會是使用標準 base64 編碼(含填補)將資料編碼為字串。接受有/無填補的標準或 URL 安全 base64 編碼。 |
int32、fixed32、uint32 | number (數字) | 1, -10, 0 | JSON 值會是十進位數字。接受數字或字串。空字串無效。 |
int64、fixed64、uint64 | string (字串) | "1", "-10" | JSON 值會是十進位字串。接受數字或字串。空字串無效。 |
float、double | number (數字) | 1.1, -10.0, 0, "NaN", "Infinity" | JSON 值會是數字或特殊字串值 "NaN"、"Infinity" 和 "-Infinity" 的其中一個。接受數字或字串。空字串無效。也接受指數符號。 |
Any (任意) | object (物件) | {"@type": "url", "f": v, ... } | 如果 Any 包含具有特殊 JSON 對應的值,則會轉換如下:{"@type": xxx, "value": yyy} 。否則,該值會轉換為 JSON 物件,並插入 "@type" 欄位以指示實際的資料類型。 |
Timestamp (時間戳記) | string (字串) | "1972-01-01T10:00:20.021Z" | 使用 RFC 3339,其中產生的輸出永遠會是 Z 標準化,並使用 0、3、6 或 9 位小數。也接受 "Z" 以外的偏移量。 |
Duration (持續時間) | string (字串) | "1.000340012s", "1s" | 產生的輸出永遠會包含 0、3、6 或 9 位小數,具體取決於所需的精確度,後面接著後綴 "s"。接受任何小數(也可能沒有),只要它們符合奈秒精確度,並且需要後綴 "s"。 |
Struct (結構) | object (物件) | { ... } | 任何 JSON 物件。請參閱 struct.proto 。 |
Wrapper 類型 | 各種類型 | 2, "2", "foo", true, "true", null, 0, ... | Wrapper 在 JSON 中使用與包裝的基本類型相同的表示法,但允許使用 null ,並在資料轉換和傳輸期間保留 null 。 |
FieldMask (欄位遮罩) | string (字串) | "f.fooBar,h" | 請參閱 field_mask.proto 。 |
ListValue (清單值) | array (陣列) | [foo, bar, ...] | |
Value (值) | value (值) | 任何 JSON 值。如需詳細資訊,請查看 google.protobuf.Value。 | |
NullValue (Null 值) | null | JSON null | |
Empty (空) | object (物件) | {} | 空的 JSON 物件 |
JSON 選項
符合規範的 protobuf JSON 實作可能會提供以下選項
永遠發出沒有存在的欄位:預設會在 JSON 輸出中省略不支援存在且具有預設值的欄位(例如,具有 0 值的隱含存在整數、空的隱含存在字串欄位,以及空的重複和對應欄位)。實作可能會提供選項來覆寫此行為並輸出具有預設值的欄位。
從 v25.x 開始,C++、Java 和 Python 實作不符合規範,因為此旗標會影響 proto2
optional
欄位,但不會影響 proto3optional
欄位。計劃在未來的版本中進行修正。忽略未知的欄位:protobuf JSON 剖析器預設應拒絕未知的欄位,但可能會提供選項來忽略剖析中的未知欄位。
使用 proto 欄位名稱而非 lowerCamelCase 名稱:預設情況下,protobuf JSON 印表機應將欄位名稱轉換為 lowerCamelCase,並將其用作 JSON 名稱。實作可能會提供選項來改為使用 proto 欄位名稱作為 JSON 名稱。Protobuf JSON 剖析器必須接受轉換後的 lowerCamelCase 名稱和 proto 欄位名稱。
將列舉值以整數而非字串形式發出:預設會在 JSON 輸出中使用列舉值的名稱。可能會提供選項來改為使用列舉值的數值。