So I am working on a project using proto buff where I need to generate golang code using .proto files.
My issue is that it is importing wrong package when I generate golang code.
So this is how my project structure looks:-
myproject/
├── protos/
│ ├── models/
│ │ ├── ad.proto
│ │ └── enums.proto
│ └── requests/
│ └── ad_request.proto
The "ad_request.proto" file requires some models or messages from "ad.proto" and "enums.proto" files
For that I imported these files and used those messages like this-
syntax = "proto3";
package my_project.requests;
import "models/ad.proto";
import "models/enums.proto";
option go_package = "github.com/name/my_project/protos/requests;requests";
so now after I generate code, a go file is made – "ad_requests.pb.go"
But the problem is that it is importing wrong package
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc (unknown)
// source: requests/ad_request.proto
package requests
import (
models "github.com/name/my_project/protos/models"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
instead of importing github.com/name/my_project/models
it is importing file from proto folder but there is no golang files in proto folder
Anyone know how to resolve this issue
This is some info on ad.proto
syntax = "proto3";
package my_project.models;
import "google/protobuf/timestamp.proto";
import "models/enums.proto";
option go_package = "github.com/name/my_project/protos/models;models";
This is the make command I use to auto generate code
.PHONY: gen proto-gen
gen proto-gen:
buf generate protos --template protos/buf.gen.yaml
protoc-go-inject-tag -input=./internal/models/*.pb.go -remove_tag_comment
protoc-go-inject-tag -input=./internal/requests/*.pb.go -remove_tag_comment
2
Answers
You added your comment after I started writing this.
I don’t use
buf
so apologies that this is pureprotoc
.I’m assuming you want to generate the Go sources alongside the protos.
The Protocol Buffers
package
hierarchy does not translate directly to the Golang module hierarchy. Your approach to usingoption go_package
is correct but I would advise against using e.g....models;models"
Here’s how I would generate your protos. I use the
--go_opt=module=${MODULE}
approach which works for me. There are other ways to achieve this.In this approach
${MODULE}
must match the prefix (as you have) for youroptions go_package={MODULE}/protos/...
Either:
The rule here is that every
*.proto
must be prefixed with one (you only have one) of the defined--proto_path
‘sOne caveat (but not bug) in your approach is that your Protocol Buffers packages should be
models
andrequests
and notmy_project.models
andmy_project.requests
.If you want these to be e.g.
package my_project.models
then you should create:This is because your current folder’s
protos
is the root of your protocol buffers files. The convention (!?) is to then reproduce the package path as a folder structure. Because you start withmy_project
, the first folder withinprotos
would bemy_project
etc.From your
Makefile
I assume you want your generated files ingithub.com/name/my_project/internal
(since you have-input=./internal/models/*.pb.go
).Your
protos/buf.gen.yaml
would be something like:protos/requests/ad_request.proto
would be:and
protos/models/enums.proto
:Then you could do:
assuming you have a
go.mod
:A. side note on conventions:
but.gen.yaml
should be at the root of the project and the usage of;
ingo_package
is discouraged.