本仓库独立承载可复用的 protobuf / gRPC 契约(proto 源文件与生成的 Go 代码),供 go-zero 项目以及其他 Go 服务共同引用。
hhs-contracts/
├── proto/ # .proto 源文件
│ ├── status.proto # 公共类型(ResponseStatus 等)
│ └── delivery.proto # 配送服务定义
├── gen/
│ └── go/
│ ├── commonpb/ # status.proto 生成的 Go 代码(独立 module)
│ │ ├── status.pb.go
│ │ ├── go.mod
│ │ └── go.sum
│ └── deliverypb/ # delivery.proto 生成的 Go 代码(独立 module)
│ ├── delivery.pb.go
│ ├── delivery_grpc.pb.go
│ ├── go.mod
│ └── go.sum
│ └── shoppb/ # shop/*.proto 生成的 Go 代码(独立 module)
├── Makefile
└── README.md
proto/ —— proto 源文件(独立目录,不与生成代码混杂)gen/go/<service>pb/ —— protoc 生成的 .pb.go(独立 Go module,外部项目直接 import)go_package 固定为 cnb.cool/haohuisong.com-2025/hhs-contracts/gen/go/<service>pbpackage 使用简单的小写标识符(如 status、cnb.delivery)import "xxx.proto"(-I 指向 proto/)需要先安装 protoc 以及 Go 插件:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
由于 delivery.proto 引用了 google/protobuf/empty.proto,生成时需要提供 protoc 自带的 include 路径,通过环境变量 GOOGLE_PROTO_INCLUDE 指定:
# macOS
export GOOGLE_PROTO_INCLUDE=$HOME/Documents/work/protoc-33.5-osx-aarch_64/include
# Windows
set GOOGLE_PROTO_INCLUDE=D:/work/protoc-33.0-win64/include
然后通过 Makefile 一键生成:
# 一次性生成全部
make pb
# 或单独生成
make pb-status
make pb-delivery
等价的裸 protoc 命令(仅作参考):
# Mac
protoc --proto_path=$HOME/Documents/work/protoc-33.5-osx-aarch_64/include --proto_path=./proto \
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative \
--go_out=./gen/go/commonpb --go-grpc_out=./gen/go/commonpb \
./proto/status.proto
protoc --proto_path=$HOME/Documents/work/protoc-33.5-osx-aarch_64/include --proto_path=./proto \
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative \
--go_out=./gen/go/deliverypb --go-grpc_out=./gen/go/deliverypb \
./proto/delivery.proto
# Windows
protoc --proto_path=D:/work/protoc-33.0-win64/include --proto_path=./proto ^
--go_opt=paths=source_relative --go-grpc_opt=paths=source_relative ^
--go_out=./gen/go/deliverypb --go-grpc_out=./gen/go/deliverypb ^
./proto/delivery.proto
生成代码后,整理 gen/go/*pb 各 module 的依赖:
make tidy
make clean
go-zero(以及其他 Go 项目)作为下游消费方,直接以 Go module 形式引用对应包即可:
import (
commonpb "cnb.cool/haohuisong.com-2025/hhs-contracts/gen/go/commonpb"
deliverypb "cnb.cool/haohuisong.com-2025/hhs-contracts/gen/go/deliverypb"
)
func example(cc grpc.ClientConnInterface) error {
client := deliverypb.NewDeliveryServiceClient(cc)
_, err := client.GetAmount(context.Background(), &deliverypb.GetAmountRequest{})
_ = commonpb.ResponseStatus{}
return err
}
如果生成的 .pb.go 只放在某个 rpc 服务内部:
现在的做法是:
proto/ 负责"协议定义"(proto 源文件)gen/go/<service>pb/ 负责"生成代码"(独立 Go module,可被任意项目复用)go-zero 等项目只需 go get 对应 module 即可在 proto/ 下新增 <name>.proto,并设置:
option go_package = "cnb.cool/haohuisong.com-2025/hhs-contracts/gen/go/<name>pb";
新建 gen/go/<name>pb/ 目录,并初始化 go.mod:
cd gen/go/<name>pb
go mod init cnb.cool/haohuisong.com-2025/hhs-contracts/gen/go/<name>pb
在 Makefile 中按 pb-delivery 的样式新增对应目标,并加入到 pb 聚合目标中。
生成并整理依赖:
make pb
make tidy