Notes - Protocol Buffers

Protocol buffers provide a language-neutral mechanism for serializing structured data. It’s like JSON, except it’s smaller and faster.

Step by step

mkdir pb
cd pb
go mod init pb

Create the people.proto file

syntax="proto3";
package tutorial;

option go_package = "./tutorial";

message Person{
  string name=1;
  int32 id=2;
}

Download compiler

Install protoc-gen-go

To generating Go package, you need to install Go protocol buffers plugin:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

Generating code

protoc --go_out=. *.proto

Use the generated package

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
	"fmt"
	"google.golang.org/protobuf/proto"
	"log"
	"pb/tutorial"
)

func main() {
	p := &tutorial.Person{
		Name: "Andrew",
		Id:   0,
	}

	data, err := proto.Marshal(p)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(data)

	np := &tutorial.Person{}
	err = proto.Unmarshal(data, np)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(np)

}

How to use timestamp.proto?

  • Import it into your .proto file
1
2
3
4
5
syntax = "proto3";
package tutorial;

import "google/protobuf/timestamp.proto";
...
  • Copy include folder(in protoc-21.1-win64.zip) into your project folder(or anywhere)
  • Specify the folder when compile by using --proto_path=./include
protoc --go_out=.  --proto_path=./include --proto_path=. *.proto  

Troubleshooting

Go package can’t be a plain text

// in people.proto
option go_package = "tutorial" // failed to compile

// when compile
pb> protoc --go_out=. *.proto
protoc-gen-go: invalid Go import path "tutorial" for "people.proto"

The import path must contain at least one period ('.') or forward slash ('/') character.

Solution: change the package name from “tutorial” to “./tutorial”

updatedupdated2022-05-312022-05-31