I’m trying to make my Go project using hexagonal architecture as described here.
In my project I’m using a gRPC communication generated with
The directories structure:
|- grpc.proto |-internal |-core |-domain |-services |- grpcprotocol
And my grpc.proto file has go_package option that points to a specific directory in my Go project
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 I’m able to generate both grpc.pb.go file in internal/core/domain directory and grpc_grpc.pb.go file inside internal/core/services/grpcprotocol directory.
However, grpc.pb.go has a go package named
grpcprotocol while it should have a package named
domain (I also use other types defined there in separate Go files).
Also grpc_grpc.pb.go file has code that uses types defined in grpc.pb.go without imports (it treats it as if it was defined in the same package).
Is it possible to split those two files into separate Go packages and enforce code that’s in grpc_grpc.pb.go to import types from domain directory instead of treating them as defined in the same package?
Your best solution here is too separate the code that you want in
grpcprotocol and the one you want into
domain, into separate files. Such as:
syntax = "proto3"; package domain; option go_package = "github.com/myuser/myrepo/internal/core/domain"; //...
syntax = "proto3"; package grpcprotocol; option go_package = "github.com/myuser/myrepo/internal/core/services/grpcprotocol"; //...
Then you could import your
domain.proto in your
grpc.proto, by simply writing
import "domain.proto";, provide a
grpc.proto are not in the same directory. And finally to reference an object from
grpc.proto you can write:
After that you can take advantage of the
--go-grpc_opt=module, to strip the module name in
go_package and generate the code at the right place. Like:
protoc --go_out=. --go_opt=module=github.com/myuser/myrepo --go-grpc_out=. --go-grpc_opt=module=github.com/myuser/myrepo *.proto
What this will do is that, it will remove
github.com/myuser/myrepo from each
go_package and basically start from the root of your module. That’s why you can do a
Hope that helps, let me know how I can further improve my answer.
- Protobuf package and
go_packageare not the same. The former is only used for protobuf in order to give context and it extends the qualified name. The
go_packageis used during go code generation.
packagein the proto file is optional, it makes things more clear and nobody can misuse you proto file without specifying the fully qualified name (little bit safer, if named properly).
Answered By – Clément Jean
Answer Checked By – Terry (GoLangFix Volunteer)