Protocol Buffers (Proto3)语法及使用
一、Protocol Buffers
在学习gRPC的过程中,发现里面用到了Protocol Buffer。于是开始了解Protocol Buffer。
Protocol Buffer既可以作为接口定义语言(IDL),又可以做为底层消息交换的格式。
参考:
二、Proto3的语法
2.1 定义消息类型
假设你要定义一个请求消息体,一个查询请求包含:一个字符串类型的query、数值类型的页码数page_number、数值类型的一页条数result_per_page。那么在一个.proto
文件中可以定义如下:
syntax = "proto3"
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
- 第一行指定要使用
proto3
的语法,如果不写第一行,默认使用proto2
语法解析器。该行必须放在非空、非注释行的第一行; SearchRequest
中定义了三个字段;
2.2 声明字段的编号
-
每一个字段都有唯一的编号;
这些编号将在消息的二进制格式中使用,一旦这些字段的编号确定之后就不应该改变。
-
编号从1到15占用一个字节,包含了字段类型和编号,编号从16到2047占用两个字节;
因此应当预留1到15点编号对常用的消息类型。
-
最小的编号为1,最大的为2^29-1(536,870,911),19000到19999是Protocol Buffer自己使用的,我们不应该使用。
类似的,你不应该使用任何自己预留的编号。
2.3 指定字段的规则*
翻译的官方文档,这里自己没读懂。
singular
:是proto3默认的字段规则,上面只能定义零个或多个字段;repeated
: 这样的字段可以重复定义任何次数(包括零次),重复的顺序值也将会保存;
2.4 添加多个消息类型
一个.proto
文件可以定义多个消息体:
syntax = "proto3"
message SearchRequest {
string query = 1;
int32 page_number = 2; // 你想看哪个页码
int32 result_per_page = 3; // 一页展示多少条数据
}
message SearchResponse {
int32 status = 1;
}
2.5 添加注释
可以向.proto
文件中添加注释,使用像C/C++
的注释语法://
或/* ... */
。
2.6 定义预留字段
如果你更新信息体,通过删除字段或者将字段注释掉,那么将来其他用户在更新这个消息类型的使用可能重新使用这些字段编号。如果随后再加载老版本的.proto
文件,就会造成一些问题。
可以使用reserved
修饰哪些要删除的字段编号或者名称(那些在json序列化时可能出问题的名称),这样当重新使用这些被reserved修饰的编号或字段,编译器就会出问题:
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
注意:你不能在一个reserved生命中混合字段编号和名称。
2.7 从.proto
文件可以生成什么
当在.proto
文件上运行protocol buffer 编译器的时候,编译器将根据你选择的语言产生对应的代码,这个代码包含了:字段的getter和setter方法、将你的消息序列化成输出流、将输入流序列化成消息。
对于Java语法,编译器将根据.proto
文件生成表示每个消息体的.java
文件,并且为每个消息类