Protocol Buffers (a.k.a, protobuf) are a mechanism for serializing structured data introduced by Google. It’s language-neutral and platform-neutral. It also provides runtime supports for several programming languages. Here we focus on how to use protocol buffers with Go.
Environment
- macOS Catalina, Version 10.15.7.
Installation
The installation of protocol buffers for Go includes two components, the protocol buffers compiler and the corresponding runtime plugin for Go.
Install the protocol buffers compiler
The protocol buffers compiler is used to compile .proto files.
-
Download the protocol buffers compiler release package. According to the
README.md, non-C++ users are recommended to use a pre-built binary.$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.0/protoc-3.19.0-linux-x86_64.zip -
Unzip the downloaded binary and place them to the
PATH. Don’t forget to update the access permission accordingly.$ unzip protoc-3.19.0-linux-x86_64.zip -d protoc-3.19.0-linux-x86_64 $ chmod 755 bin -R $ chmod 755 include -R $ sudo cp bin/* /usr/local/bin/ $ sudo cp -r include/* /usr/local/include/ -
Try the binary.
$ protoc --version libprotoc 3.19.0
Install the Go runtime plugin
-
Install the Go runtime plugin.
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -
The binary is placed to the
GOPATH. Copy it to thePATH.$ sudo cp $(go env GOPATH)/bin/protoc-gen-go /usr/local/go/bin/ -
Try the binary.
$ protoc-gen-go --version protoc-gen-go v1.27.1
Hello, World!
More details can be referred to the official tutorial.
-
Create a
.protofile, e.g.,hello_world.proto.syntax = "proto3"; package hello_world; option go_package = "/protobuf"; message HelloWorld { string HelloWorld = 1; }packageis a package declaration for protocol buffers, which helps to prevent naming conflicts.go_packagedefines the import path of the package generated from this.protofile. Note that the import path must contain at least one period (.) or forward slash (/) character.messageis an aggregate containing a set of typed fields.
-
Compile the
.protofile.$ protoc -I=. --go_out=. ./hello_world.proto- The first parameter
-Ispecifies the source directory where the application’s source code lives. - The second parameter
--go_outspecifies the destination directory where the generated code from the.protofile will go. - The third parameter specifies the path of the
.protofile.
The above command will generate
./protobuf/hello_world.pb.go. - The first parameter
-
Create the Go code for testing.
$ go mod init hello_world $ go mod tidyCreate a Go file with the
mainpackage for testing, e.g.,hello_world.go.package main import ( "fmt" "hello_world/protobuf" ) func main() { p := protobuf.HelloWorld{ HelloWorld: "Hello, World!", } fmt.Println(p.HelloWorld) }Run the test.
$ go run hello_world.go Hello, World!
The hierarchy of all above files can be summarized as below.
- go.mod
- go.sum
- hello_world.go
- hello_world.proto
- protobuf
- hello_world.pb.go