我发现这是 Protobufs(和 gRPC)更令人困惑的方面之一。
我认为要解决的问题是 Protobufs 需要:
- 允许命名空间范围服务|消息到例如 DNS 域
- 支持多种编程语言(以不同的方式实现命名空间)。
protoc
具有允许v1/api
使用 protobuf 选项(例如)将例如 protobuf 的包(例如)映射到特定于语言的命名空间的选项go_package
。请参阅Go为 Golang 生成的代码。
这在使用 Go Modules 时稍微复杂一些,但总而言之,您遇到的可能是上述情况的某种(意外)组合,示例代码假定一个模块名称,并protoc
建立在另一个模块名称的假设之上。
TL;DR 更新代码的模块引用以反映正确生成的pb
路径。如果生成代码位于错误的位置,您只需将其移动到正确的子目录(路径),但最好更新您的protoc
命令以将文件生成到正确的目录。
例子
something.proto
:
syntax = "proto3";
package v1alpha1;
option go_package = "github.com/me/my-protos;v1alpha1";
注意 go_package
将 proto 包别名为v1alpha1
我想github.com/me/my-protos
在 Golang 中引用的内容。
然后我生成:
MODULE="github.com/me/my-protos"
protoc \
--proto_path=. \
--go_out=./api/v1alpha1 \
--go_opt=module=${MODULE} \
--go-grpc_out=./api/v1alpha1 \
--go-grpc_opt=module=${MODULE} \
./something.proto
注意此示例也生成 gRPC 代码。它避免(!)为生成的代码protoc
创建路径github.com/me/my-protos
,因为我在该存储库中生成源代码。我只想要创建文件的相对路径./api/v1alpha
。
产生:
my-protos
├── something.proto
├── api
│ └── v1alpha1
│ ├── something_grpc.pb.go
│ └── something.pb.go
├── go.mod
├── go.sum
└── README.md
我可以导入:
import (
pb "github.com/me/my-protos/api/v1alpha1"
)
注意从不同的仓库,我现在可以访问我的 protos 仓库,结合 reprogithub.com/me/my-project/api/v1alpha1
和生成的位置来提供我想要的路径。