Protocol-Buffers

Last Update : 07 August, 2023 | Published : 27 April, 2023 | 4 Min Read

Protocol Buffers are a core part of gRPC and are used to define the service interfaces and the messages that are exchanged between the client and server.

In gRPC, you define your service using Protocol Buffers in a .proto file, which specifies the methods that the service exposes and the types of messages that are exchanged. The .proto file is then compiled using the Protocol Buffers compiler to generate the code that can be used to implement the service and the client.

When a client makes a request to a gRPC server, it sends a Protocol Buffers-encoded message that contains the data required for the request. The server receives the message and uses the generated code to deserialize the message and extract the relevant data.

Similarly, when the server sends a response back to the client, it encodes the response data as a Protocol Buffers message and sends it to the client. The client then deserializes the message and extracts the response data.

That’s enough defining protocol buffers,so let’s do some practical demonstration:

First thing to do is to create a message type:

syntax = "proto3";
package api.v1;

message Person {
  string name = 1;
  int32 age = 2;
  repeated string hobbies = 3;
}

In this example, we define a message type called Person. The message has three fields: name, age, and hobbies. This is just a simple example of how to create a message type using proto3 syntax. In practice, message types can be much more complex and can include nested messages, enums, and other types of fields.

Then let’s install the protobuf compiler:

$ brew install protobuf

make sure it’s installed using the following command:

$ protoc --version

Now install proto-gen-go

$ brew install grpc 
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26

and then add it to your path in env variables:

export PATH="$PATH:$(go env GOPATH)/bin"

Note:This command works only on MacOS but if your OS is Windows,then you have to go to env variables and add it manually

Create a .proto file with the Person message type: you can use the example I provided earlier.

Compile the .proto file: run the following command to generate the Go code:

protoc --go_out=paths=source_relative:. person.proto

This command tells the Protocol Buffers compiler to generate Go code from the person.proto file and output it to the current directory (–go_out=.). The paths=source_relative option tells the compiler to generate the output files using relative paths.

Check the generated Go code: you should see a person.pb.go file in the api/v1 directory. This file contains the Go struct for the Person message type. Here is what the generated code should look like:

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.27.1
// 	protoc        v3.17.3
// source: person.proto

package v1

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
)
...

type Person struct {
	Name    string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Age     int32    `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
	Hobbies []string `protobuf:"bytes,3,rep,name=hobbies,proto3" json:"hobbies,omitempty"`
}

Now that we have things working for one message type,let’s define service:

syntax = "proto3";

package api.v1;

message Person {
  string name = 1;
  int32 age = 2;
  repeated string hobbies = 3;
}

service PersonService {
  rpc GetPerson(GetPersonRequest) returns (Person) {}
  rpc AddPerson(AddPersonRequest) returns (AddPersonResponse) {}
}

message GetPersonRequest {
  string name = 1;
}

message AddPersonRequest {
  Person person = 1;
}

message AddPersonResponse {
  string message = 1;
}

Now let’s generate generate the client and the service code using protoc again.

protoc --go_out=. --go-grpc_out=. person.proto

This command generates two Go files:

  • person.pb.go: contains the generated code for the Person message type.
  • person_grpc.pb.go: contains the generated code for the PersonService gRPC service interface.

The –go_out option generates Go code for the protocol buffers and the –go-grpc_out option generates the Go code for the gRPC service.

Now that all the required code is generated, it’s time for me to build the server-side will be continued in the next blog….

Looking for Cloud-Native Implementation?

Finding the right talent is pain. More so, keeping up with concepts, culture, technology and tools. We all have been there. Our AI-based automated solutions helps eliminate these issues, making your teams lives easy.

Contact Us