我正试图用here所描述的六边形架构来完成我的Go项目.

目录 struct :

|- grpc.proto
|-internal
  |-core
    |-domain
  |-services
    |- grpcprotocol

我的grpc.proto文件有go_包选项,指向go项目中的特定目录

syntax = "proto3";
option go_package = "github.com/myuser/myrepo/internal/core/services/grpcprotocol";
...

使用protoc --go_out=internal/core/domain --go_opt=paths=source_relative --go-grpc_out=internal/core/services/grpcprotocol --go-grpc_opt=paths=source_relative ports.proto,我能够生成internal/core/domain目录下的grpc.pb.go文件和internal/core/services/grpcprotocol目录下的grpc_grpc.pb.go文件.

然而,grpc.pb.go有一个名为grpcprotocol的go包,而它应该有一个名为domain的包(我还使用在单独的go文件中定义的其他类型).

是否可以将这两个文件拆分为单独的Go包,并强制执行grpc_grpc.pb.go中的代码,以便从域目录导入类型,而不是按照同一个包中的定义来处理它们?

推荐答案

这里最好的解决方案是将grpcprotocol中需要的代码和domain中需要的代码分离到单独的文件中.例如:

域名.因此

syntax = "proto3";
package domain;
option go_package = "github.com/myuser/myrepo/internal/core/domain";

//...

grpc.因此

syntax = "proto3";
package grpcprotocol;
option go_package = "github.com/myuser/myrepo/internal/core/services/grpcprotocol";

//...

然后你可以在你的grpc.因此中导入你的域名.因此,只需写import "域名.因此";,如果域名.因此grpc.因此不在同一个目录中,就可以提供--proto_path.最后,要引用grpc.因此域名.因此的一个对象,你可以写:

domain.AnObject

之后,您可以利用--go_opt=module--go-grpc_opt=module,在go_package中go 掉模块名,并在正确的位置生成代码.比如:

protoc --go_out=. --go_opt=module=github.com/myuser/myrepo --go-grpc_out=. --go-grpc_opt=module=github.com/myuser/myrepo *.proto

这将做的是,它将从每个go_package中删除github.com/myuser/myrepo,基本上从模块的根开始.这就是为什么你可以做--go_out=.--go-grpc_out=..

希望这能有所帮助,让我知道如何进一步改进我的答案.

笔记

  • Protobuf软件包和go_package不一样.前者仅用于protobuf以提供上下文,并扩展了限定名.go_package用于生成go代码.
  • proto文件中的package是可选的,它让事情变得更清楚,没有人可以在不指定完全限定名的情况下滥用proto文件(如果命名正确,会更安全一点).

Go相关问答推荐

为什么工具链指令在这种情况下没有效果?

如何在jsonrpc服务器的服务器端捕获错误?

无法获取RPC描述符

可以';t从主机连接到ScyllaDB容器

go mod tidy会自动升级go.mod中的go版本吗?

无效操作:v > max(类型参数 T 与 > 不可比较)

Go:如何在不加载正文的情况下创建 http 代理通行证

testcontainers:如何修复绑定源路径不存在

带有前导零的整数参数被 flag.IntVar 解析为八进制

闭包所处的环境范围是什么?

获取不带类型参数的泛型 struct 的类型名称

Golang - 客户 Unmarshaler/Marshaler 在指针上具有 nil/null 值

如何使用struct的方法清除除某些字段之外的struct值

如何使用特定的 Go 版本运行 govulncheck?

每次有人进入我的网站时如何运行特定功能?

在 Go 中读取数字行

Go 导入范围查找 protobuf 类型

如何在 Go 中使用 Pact 返回错误请求(400、500)?

try 执行`go test ./... -v`时,Golang中有没有办法设置标志

如何使用 fyne 避免 GUI 应用程序中的循环依赖?