将 gRPC/protobuf 与 go multirepo 和 go 模块一起使用

Using gRPC/protobuf with a go multirepo and go modules

我正在尝试让 protocprotoc-gen-go 使用 go 模块在多回购代码库中发挥出色。

在我的“api”(即 protobuf)回购协议中引入了一个主要版本更新之前,我已经设法让事情或多或少地工作,并且我遇到了一些问题屏障.

这是我的设置的简化图片:

假设我有两个回购协议,github.com/kpruden/base-apigithub.com/kpruden/dep-api

base-api 包括 base-api.proto 和从中生成的 base-api.pb.go

类似地,dep-api包含dep-api.proto和相应的生成代码。此外,dep-api.proto 通过 import github.com/kpruden/base-api/base-api.proto 语句依赖于 base-api.proto

base-apidep-api 都使用 go 模块,dep-apigo.mod 指定对 base-api.

的依赖

为了完成这项工作,我可以 运行 go mod vendordep-api 存储库中将其所有依赖项拉入 vendor 目录,然后添加 -I./vendor 我打电话给 protoc.

在我决定需要发布 base-api 的主要版本之前,这一切都很好。这是通过将 base-api/go.modmodule 行更新为 /v2 来完成的。我不需要保留版本 1,所以我没有在我的 repo 中创建 v2 子目录,并且版本 2 代码和 protobuf 定义存在于 repo 的根目录中。

起初,这似乎不是问题。由于我没有移动任何文件,protoc 仍然可以找到 base-api.proto。但是,在生成的go代码中,必须使用import "github.com/kpruden/base-api/v2"导入base-api的版本2,但是protoc正在生成代码以在github.com/kpruden/base-api.[=47=导入它]

我的问题是:如何让 protocdep-api 生成 go 代码以在正确的模块路径中导入 base-api?这可能吗? None protobuf 或 gRPC 的文档有很多关于 go 模块的内容。 Google 导致我在这些项目中遇到了一些 github 问题,这些问题谈论支持 go 模块,但它们大多是内部讨论,没有太多规定,我发现没有任何地方提到处理主要版本发布。

我能够得到一些工作。我在问题中描述的设置实际上非常接近最终的结果。

总而言之,大部分事情都按预期进行:

  1. 在父模块中,通过将 /v2 附加到 go.mod 中的 module 行来实现主要版本提升。不需要其他任何东西。特别是,源代码管理中的目录布局不需要 v2 任何地方。
  2. 在子模块中引用父模块的v2在go代码中处理正常。使用上面的例子,一个简单的 import "github.com/kpruden/base-api/v2" 就可以做到。
  3. 包含父 protobuf 定义时,使用模块路径:import "github.com/kpruden/base-api/v2/base-api.proto"
  4. 为了能够使用 protoc 生成绑定,请使用 go mod vendor 将依赖项复制到 ./vendor 中,这将放置它们以便可以找到 protobuf 定义和导入路径(3).此时 protoc -I./vendor ... 按预期工作,生成的 go 源中的导入是正确的,每个人都很高兴 :)