Protocol Buffers with Go: Hello World!

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.

  1. 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
    
  2. 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/
    
  3. Try the binary.

    $ protoc --version
    libprotoc 3.19.0
    

Install the Go runtime plugin

  1. Install the Go runtime plugin.

    $ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    
  2. The binary is placed to the GOPATH. Copy it to the PATH.

    $ sudo cp $(go env GOPATH)/bin/protoc-gen-go /usr/local/go/bin/
    
  3. Try the binary.

    $ protoc-gen-go --version
    protoc-gen-go v1.27.1
    

Hello, World!

More details can be referred to the official tutorial.

  1. 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.
  2. 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.

  3. 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

Contents