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
.proto
file, e.g.,hello_world.proto
.syntax = "proto3"; package hello_world; option go_package = "/protobuf"; message HelloWorld { string HelloWorld = 1; }
package
is a package declaration for protocol buffers, which helps to prevent naming conflicts.go_package
defines the import path of the package generated from this.proto
file. Note that the import path must contain at least one period (.
) or forward slash (/
) character.message
is an aggregate containing a set of typed fields.
-
Compile the
.proto
file.$ protoc -I=. --go_out=. ./hello_world.proto
- The first parameter
-I
specifies the source directory where the application’s source code lives. - The second parameter
--go_out
specifies the destination directory where the generated code from the.proto
file will go. - The third parameter specifies the path of the
.proto
file.
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 tidy
Create a Go file with the
main
package 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