[Note] Protocol Buffer 筆記
Language Guide (proto3) @ Google Developers
如果單純只使用 protocol buffer 的 go 套件,並沒有實作 go-grpc 的功能,若需要在 grpc 中使用 protocol buffer 需進一步參考 go-grpc
為什麼使用 Protocol Buffer 而非 JSON
JSON 的好處
- 資料可以用任何形式,例如陣列、nested object
- 在 Web 中被廣泛使用,且作為資料交換的方式
- 多數語言都能解讀
Protocol Buffer 的好處
- gRPC 使用 protocol buffer
- 更快:payload size 比 JSON 小非常多,可以節省非常多耗用的流量
- 效能更好:Parse JSON 是屬於 CPU intensive 的任務;protocol buffer 則是 binary format 的資料,更接近底層機器用來表徵資料的方式,因此所需消耗的 CPU 資源較少
- 能夠清楚定義型別(data types) ,並且有資料交換的 schema
- 可以寫註解在內
- 自動產生可以使用的程式碼(例如,gRPC)
Protocol Declaration
syntax = "proto3";
package sandbox.protobuf_sandbox.proto.addressbook;
option go_package = "sandbox/protobuf-sandbox/proto";
import "google/protobuf/timestamp.proto";
package
是用來避免在不同專案之間的名稱衝突go_package
是選填的(option),用來載入 proto 編譯後的檔案
定義 Message Type
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
- field:在 message 中每一行都是一個 field,並包含有名稱(name)和型別(type)
- field type:每個欄位的第一個值是用來定義該欄位的型別
- field number:每個欄位的最後有一個數字,這是數字將是唯一值(unique number),用來在 message binary format 中辨認欄位用
field number
可以看到每一個欄位都含有一個獨特的數字(unique number),這個數字是用來在 message binary format 中辨認欄位用的,一旦這個 message type 正在使用中就不應該再改變它,因此撰寫時並不一定要照著數字的順序,只要確保它是唯一個。由於數字 115 會使用 1 個 byte,數字 162047 會使用 2 個 byte,因此一般來說,會把最常用到的欄位使用 115 來編碼,但也要記得預留 115 的空間,因為未來可能會新增其他常用到的欄位。
數字可以從 1 一直到 536,870,911(2^29 -1
),但你不能使用 19000~19999 這個區間,因是這個區間是給 Protocol Buffer 實作用的
被保留的欄位(reserved fields)
在建立好 proto 檔後,未來更新 message 時若是直接移除(註解)掉某個欄位時,後續維護的開發者在不知情的情況下,可能會用到曾經被使用過的 field number,由於 gRPC 是透過 field number 來辨別欄位,因此重複的 field number 將會導致嚴重的問題。
為了避免這個問題,是把曾經使用過的 field numbers 註記保留下來,未來 protocol buffer 在 compiled 時如果有使用到這些 reserved fields 時就會提出警告 。
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
型別
Protocol Buffers: Language Guide @ Google Developers