问题背景:
最近一直在使用 go-zero 微服务框架,其中让人最头疼的问题便是如何管理proto文件,因为他不能导入其他路径的包,就导致出现了很多次重复命名、不断地结构体转换等问题。
参考解决方法:
我将相同的结构体封装成了一个单独的module模块,然后上传到github再在proto文件中导入他。
参考文章:golang proto import 到底怎么做? 为什么? - 掘金 (juejin.cn)
这会导致自己的数据结构公开到
github,如果你非常忌讳这种事情,或许可以试试本文推荐的方式
解决方法:
与上述方法相同,但是不将文件上传到github,而是将 option go_package 改成自己的项目目录。
我的demo目录如下:
其中app是存放项目主要逻辑(api、rpc)的目录,而model,则是存放相同protobuf结构体的目录,其中你可以以不同模块的名称来区分,我将订单表的相同结构体放到了model/order_vars/目录下
这是 order_vars.proto 文件内容:
syntax = "proto3";
option go_package = "protoDemo/model/order_vars";
package order_vars;
message goods {
string goodsId = 1; // 商品ID
string title = 2; // 商品名称
string details = 3;
float price = 4; // 单价
repeated string pictures = 5; // 商品轮播图
bytes parameter = 6;
}
message order {
uint64 Id = 1;
string Sn = 2; // 订单号
uint64 UserId = 3; // 客户信息
uint64 StaffId = 4; // 师傅信息
string Address = 5; // 地址
string Tel = 6; // 客户手机号
string Remark = 7; // 客户备注
int64 ReservationTime = 8; // 预约时间
int64 CreateTime = 9; // 创建时间
int64 StartTime = 10; // 开始时间
int64 EndTime = 11; // 结束时间
int64 OrderType = 12; // 类型
int64 Status = 13; // 状态
float Earning = 14; // 费用
}
我们现在生成他的Go文件,输出到model/order_vars/目录下!
protoc order_vars.proto --go_out=paths=source_relative:order_vars --go-grpc_out=paths=source_relative:order_vars
输出后的目录如下:
order.proto 的内容如下:
syntax = "proto3";
option go_package = "./pb";
package order;
import "order_vars.proto";
message NewOrderReq {
order_vars.goods goods = 1;
}
message NewOrderResp {
order_vars.order order = 1;
}
service orders {
rpc NewOrder(NewOrderReq) returns (NewOrderResp);
}
现在生成他的rpc服务
$ goctl rpc protoc order.proto --go_out=../app/order/rpc --go-grpc_out=../app/order/rpc --zrpc_out=../app/order/rpc --style=go_zero
Done.
要点
option go_package表示被导入之后的import名称,可以灵活使用该参数,如果没有被导入,可以不指定。- 公共结构体使用
protoc直接生成。 - 建议将proto文件统一放到一个目录中(方便彼此调用,不过这可能会遇到其他问题,自己研究下吧)。
最后
在上述图片中,rpc服务已经生成了,另外他的公共结构体也没有报错,说明可以正常使用。
如果有什么其他问题,欢迎在评论区留言。
我用的目录结构并不是企业级别的哈,可以根据自己的业务或者规范去改,全文中最重要的便是
option go_package表示被导入之后的import名称