我正在尝试使用六角形架构来制作我的 Go 项目,如 here 所描述的那样。 。
在我的项目中,我使用 protoc
生成的 gRPC 通信来自.proto
文件。
目录结构:
|- grpc.proto
|-internal
|-core
|-domain
|-services
|- grpcprotocol
我的 grpc.proto 文件有 go_package 选项,它指向我的 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 文件,并在中生成 grpc_grpc.pb.go 文件em>internal/core/services/grpcprotocol 目录。
但是,grpc.pb.go 有一个名为 grpcprotocol
的 go 包而它应该有一个名为 domain
的包(我还使用单独的 Go 文件中定义的其他类型)。
此外, grpc_grpc.pb.go 文件包含使用 grpc.pb.go 中定义的类型的代码,无需导入(它将其视为在同一包中定义)。
是否可以将这两个文件拆分为单独的 Go 包,并强制执行 grpc_grpc.pb.go 中的代码从域目录导入类型,而不是将它们视为同一包中定义的类型?
最佳答案
这里最好的解决方案是将您想要在 grpcprotocol 中的代码和您想要在 domain
中的代码分开到单独的文件中。如:
域名.proto
syntax = "proto3";
package domain;
option go_package = "github.com/myuser/myrepo/internal/core/domain";
//...
grpc.proto
syntax = "proto3";
package grpcprotocol;
option go_package = "github.com/myuser/myrepo/internal/core/services/grpcprotocol";
//...
然后,您可以在 grpc.proto
中导入 domain.proto
,只需编写 import "domain.proto";
,提供如果 domain.proto
和 grpc.proto
不在同一目录中,则为 --proto_path
。最后,要在 grpc.proto
中引用 domain.proto
中的对象,您可以编写:
domain.AnObject
之后,您可以利用 --go_opt=module
和 --go-grpc_opt=module
来去除 go_package< 中的模块名称
并在正确的位置生成代码。喜欢:
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 - protobuf 与 grpc for Go 在拆分包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71944360/