Protocol Buffers學習(1):定義一個消息

首先讓咱們來看一個很是簡單的例子。 假設你想定義一個消息格式,用來表示搜索請求,其中每一個搜索請求都有三項:javascript

  • 一個查詢字符串
  • 你感興趣的特定結果頁
  • 以及每一個頁面的結果數

下邊是用來定義消息類型的.proto文件java

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}複製代碼
  • 第一行表示使用的protocol版本是3,若是你不寫這一條,protobuf會認爲你使用的是protobuf2,並且,這行必須是第一行,前邊也不能有註釋
  • SearchRequest這條消息定義了三個字段(名稱/值對),每條消息都要包含這三個字段,每一個字段都有一個名稱和一個類型

字段類型說明

在上面的例子中,全部字段都是基本類型:兩個整數(page_number和result_per_page)和一個字符串(query)。這些字段也能夠是複合類型,包括枚舉和其餘消息類型ui

字段標籤

消息定義中的每一個字段都有惟一的編號標籤,這些標記用於以消息二進制格式標識字段,消息開始使用以後就不能修改編碼

注意spa

  • 值在1到15範圍內的標籤須要一個字節進行編碼,包括標識號和字段類型
  • 在16到2047範圍內的標籤佔用兩個字節。

所以,你應該爲很是頻繁出現的消息元素保留標籤1到15。記住要爲可能在未來添加的頻繁出現的元素留出一些空間。code

最小的標籤是1,最大的標籤是536870911,即2^29 - 1,而且19000 - 19999protobuf系統保留標籤,不能使用這幾個接口

字段規則說明

一共有兩種類型ip

  • singular: 一個符合規則的消息應該具有零個或者一個該字段
  • repeated: 一個符合規則的消息能夠有零個或者任意個該字段,而且保留重複的順序,在proto3中,基本類型的重複字段默認壓縮編碼

添加更多消息類型

能夠在單個.proto文件中添加多個消息類型,例如字符串

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
 ...
}複製代碼

添加註釋

可使用//.proto文件添加註釋。例如編譯器

message SearchRequest {
  string query = 1;
  int32 page_number = 2;  // Which page number do we want?
  int32 result_per_page = 3;  // Number of results to return per page.
}複製代碼

保留字段(字段修改或者刪除解決辦法)

當消息類型更新或者刪除時,這些被修改的字段的標籤若是繼續使用,會形成數據不正確的問題,這時須要把這些標籤保留起來,防止跟舊版本的數據發生衝突。
(當使用JSON序列化時,字段名稱也有可能存在這個問題),通俗來講,就至關於已經上線了使用A接口的一個APP,這個時候服務端若是想修改A接口的數據格式,只能新增一個接口,而且確定不能使用A接口的地址

案例

message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}複製代碼

這就表示 2,15,9,10,11,"foo", "bar"都不能重複使用了

.proto文件會生成什麼?

當編譯.proto文件時,編譯器將根據你選擇的語言生成對應代碼,你須要使用文件中描述的消息類型,包括獲取和設置字段值,將消息序列化 輸出流,以及解析來自輸入流的消息

  • 對於PHP,編譯器會爲每一個消息生成一個類,用來描述該消息
  • 對於C ++,編譯器從每一個.proto生成.h.cc文件,併爲您的文件中描述的每一個消息類型指定一個類
  • 對於Java,編譯器會爲每一個消息類型生成一個帶有類的.java文件,以及用於建立消息類實例的特殊Builder類
  • Python有點不一樣, Python編譯器生成一個模塊,其中包含.proto中每一個消息類型的靜態描述符,而後使用元類在運行時建立必要的Python數據訪問類
  • 對於Go,編譯器會爲文件中的每種消息類型生成一個具備類型的.pb.go文件
  • 對於Ruby,編譯器生成一個包含消息類型的包含Ruby模塊的.rb文件
  • 對於JavaNano,編譯器輸出與Java相似,但沒有Builder類
  • 對於Objective-C,編譯器從每一個.proto生成一個pbobjc.hpbobjc.m文件,在文件中描述的每一個消息類型都有一個類
  • 對於C#,編譯器從每一個.proto生成一個.cs文件,在文件中描述的每一個消息類型都有一個類
相關文章
相關標籤/搜索