1. 指明版本
.proto文件中使用proto3的語法需要在開頭聲明:
syntax="proto3"
2. 定義消息
syntax = "proto3"; message AddUserReq { string name = 1; string password = 2; sint64 group_id = 3; }
消息的字段聲明由4部分構成:字段修飾符 字段類型 字段名稱 = 標志號
1) 字段修飾符
* singular : 默認值,該字段可以出現0次或者1次(不能超過1次)。
* repeated : 該字段可以重復任意多次(包括0次)。proto3中,repeated默認使用packed。
proto3中在語法層將required移除,singular是由optional改名而來。
2) 字段類型
.proto type | Notes | C++ type | Go type |
double | double | float64 | |
float | float | float32 | |
int32 | 使用變長編碼,對於負值的效率很低,如果該域有可能有負值,使用sint64替代 | int32 | int32 |
int64 | int64 | int64 | |
uint32 | 使用變長編碼 | uint32 | uint32 |
uint64 | 使用變長編碼 | uint64 | uint64 |
sint32 | 使用變長編碼,處理負值時比int32高效 | int32 | int32 |
sint64 | 使用變長編碼,處理負值時比int64高效 | int64 | int64 |
fixed32 | 固定4個字節,如果數值總是比228大,此類型比uint32高效 | uint32 | uint32 |
fixed64 | 固定8個字節,如果數值總是比256大,此類型比uint64高效 | uint64 | uint64 |
sfixed32 | 固定4個字節 | int32 | int32 |
sfixed64 | 固定8個字節 | int64 | int64 |
bool | bool | bool | |
string | 一個字符串,必須是UTF-8編碼或7-bit ASCII編碼 | string | string |
bytes | 可能包含任意順序的字節數據 | string | []byte |
默認值:
* string類型默認值是空字符串,不是null
* bytes類型默認是空bytes
* bool類型默認值是false
* 數字類型默認值是0
* 枚舉類型默認值是第一個枚舉值,即0
* repeated修飾的字段,默認值是空(在對應的編程語言中通常是一個空的list)
3) 標志號
每一個被定義在消息中的字段都會被分配一個唯一的標量,這些標量用於標志定義在二進制消息格式中的屬性。標量一旦被定義就不允許在使用過程中再次被改變。
1~15的標志號在編碼的時候會占用一個字節,16~2047的標志號則占用兩個字節,所以應該為頻繁出現的消息元素保留1~15的標志號。
保留標識符(reserved)可以避免其他人在未來使用不該使用的標志號。
message Foo { reserved 2, 15, 9 to 11; reserved "foo", "bar"; }
3. 枚舉
message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; enum Corpus { UNIVERSAL = 0; WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6; } Corpus corpus = 4; }
Corpus枚舉類型的第一個枚舉值是0,每一個枚舉值定義都會與一個常量映射,而這些常量的第一個常量必須為0。
4. 導入其它.proto中定義的消息
import "test/result.proto";
5. 包
可以為.proto文件指定包名,防止消息名沖突。
6. 服務定義
如果想在RPC中使用已經定義好的消息類型,可以在.proto文件中定一個消息服務接口,protocol buffer編譯器會生成對應語言的接口代碼。
service SearchService { // 方法名 方法參數 返回值 rpc Search(SearchRequest) returns (SearchResponse); }