protobuf

使用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);
}
上一篇下一篇

猜你喜欢

热点阅读