Go_generate_protobuf
Playground for Go Generate Using Proto Files⌗
This is a small application to demonstrate how to use go generate
to compile proto files into Go code.
Note: all code is available on GitHub here.
Go Generate⌗
The original blog post by Rob Pike is well worth a read. At the bottom, Rob says
Please use go generate creatively. It’s there to encourage experimentation.
This is one such experimentation.
Protobuf, gPRC, and Generating Code⌗
If you are unfamiliar with Protocol Buffers and gRPC, those linked resources are worth a read. However, just know that Protobuf is a language spec that allows you to define abstract API contracts within generated code stubs. Your application needs to implement these interfaces for clients to consume. The benefit is that both client and server consume and fulfill requests using the same base .proto
file and its generated code, allowing for incredible type safety.
Protoc Hassles⌗
Go developers using Protobuf for a few years are probably familiar with the protoc
binary used and the protoc-gen-go
plugin. This is the tool we use to generate Go stubs from proto files. Protoc commands can be provided via scripts, in Dockerfiles, or ran directly to ensure that code is generated and types are accessible to your application. This decouples the proto compilation step from your app compilation. If you want to couple the two together, go generate
may be your answer.
Go Generate (again)⌗
The go generate
command searches through your Go files for the //go:generate
comment (notice no space between the slashes and go
). Adding this tag tells the Go toolchain to run whatever shell commends follow.
Tagging for Go Generate⌗
You can see here that main.go
has two go generate tags.
//go:generate protoc --go_out=. --go-grpc_out=. proto/helloapis/messages.proto
//go:generate protoc --go_out=. --go-grpc_out=. proto/helloapis/services.proto
These two tags will compile protos found in proto/helloapis
and move them into the directory indicated by their package name. In this instance, that directory is gen/helloapis/v1
.
Building the Application⌗
Attemping to run go build .
before compiling the protos will fail.
❯ go build . client/client.go:6:2: package playgen/gen/helloapis/v1 is not in std (/snap/go/10630/src/playgen/gen/helloapis/v1)
To resolve this, run go generate ./...
.
❯ go generate ./…
Notice that a new gen
directory is in the repo root.
❯ ls
build client docker-compose.yaml gen go.mod go.sum main.go proto README.md server
The application is now buildable and runnable!
❯ go build .
❯ ls
build client docker-compose.yaml gen go.mod go.sum main.go playgen proto README.md server
❯ ./playgen
Hello, vim-go!