使用gRPC的踩过的那些坑
2018-12-07 本文已影响0人
go4awalk
1、rpc接口的参数和返回值必须是message类型
即使接口不需要参数或返回值,也得指定一个message。
这也导致不能不传参数,也不能不返回结果,也不能使用基本类型作为参数和返回结果(因为基本类型不是message),而我们项目中的实际接口经常需要这么做,比如无条件获取用户列表,这种矛盾怎么解决呢?当然是定义message。。。
为了满足rpc的接口要求,期初我在项目中为rpc用到的基本类型做了封装,比如:
global.proto
syntax = "proto3";
option java_package = "com.example";
option java_outer_classname = "CommonProto";
message Int32 {
int32 value = 1;
}
message Bool {
bool value = 1;
}
syntax = "proto3";
import "global.proto"
option java_package = "com.example";
option java_outer_classname = "UserProto";
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
message Int32 {
int32 value = 1;
}
service UserSevice {
rpc getById(Int32) returns (User);
}
然后可以把Int32这个封装message放到一个单独的proto文件中,这样其他proto可以通过import共用这些通用的与业务无关的message。
后来偶然间发现,protobuf 自己定义好了基本类型的封装message:Int32Value、BoolValue等等,那么我们还是直接拿来用吧。
import "google/protobuf/wrappers.proto";
service UserSevice {
rpc getById(google.protobuf.Int32Value) returns (User);
}
Java代码:
Int32Value value = Int32Value.newBuilder().setValue(1).build();
简写为:Int32Value value = Int32Value.of(1);
那么不想传参和返回结果时怎么办呢?
答案是使用protobuf提供的Empty,这个message没有属性,不需要设置Empty message,而且客户端在调用gRPC接口时,不需要构造Empty对象,直接传null即可,减少gRPC接口的这一规定对客户端的影响。
syntax = "proto3";
import "google/protobuf/empty.proto";
option java_package = "com.example";
option java_outer_classname = "UserProto";
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
message UserList {
repeated User user = 1;
}
service UserSevice {
rpc list(google.protobuf.Empty) returns (UserList);
}