go - protobuf 与 grpc for Go 在拆分包中

标签 go protocol-buffers grpc protoc grpc-go

我正在尝试使用六角形架构来制作我的 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.protogrpc.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/

相关文章:

linux - Go、sudo 和 apache 端口 80

java - Protobuf 错误 :Protocol message tag had invalid wire type

c++ - 程序状态和调试器不一致

user-interface - Walk GUI Toolkit for GO 中的文件选择器组件

rest - golang restful api中的全局变量

go - 如何在 proto3 中复制未知字段功能?

java - 如何使用 keystore 在 grpc 中使用 java 启用 ssl

c# - 如何让grpc像WCF一样抛出原始异常?

json - 动态创建某种类型的结构并将 JSON 解码到该实例中

java泛型问题