Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
13 Jun 2025 · 5 min read ·Article 5 / 110
Go

5 Setting Up Protocol Buffers (protobuf) for gRPC

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

If you’re building modern microservices with gRPC, one of the most important foundations you’ll touch repeatedly is Protocol Buffers (protobuf). This article is the fifth part of the gRPC introduction series, and we’ll focus on how to set up protobuf to be used as the communication interface in a gRPC system. I’ll walk you through everything from the concepts and setup to an implementation example along with a simulation of client-server communication.


Why Protocol Buffers?

Before we write any code, let’s first understand the reasoning. Protocol Buffers is a data serialization format developed by Google that offers speed, efficiency, and broad language support. Unlike JSON or XML, protobuf produces far more compact data and parses much faster — the main reason this technology became the backbone of gRPC.

A Quick Comparison

Data FormatData SizeSerialization SpeedSupported Languages
JSONLargeSlowAll
XMLVery largeSlowAll
Protocol BuffersSmallVery fastMany

Protocol Buffers Fundamentals

Before setting up protobuf, understand its basic format: the .proto file. Inside this file, we define:

  • Messages: like a data schema (similar to a class)
  • Services: the operations available for gRPC

A simple .proto gRPC example:

proto
 1syntax = "proto3";
 2
 3package user;
 4
 5service UserService {
 6  rpc GetUser (GetUserRequest) returns (GetUserResponse);
 7}
 8
 9message GetUserRequest {
10  string user_id = 1;
11}
12
13message GetUserResponse {
14  string user_id = 1;
15  string username = 2;
16  string email = 3;
17}

Steps to Set Up Protobuf

Let’s break down, step by step, the protobuf setup for a microservice project using gRPC. For this tutorial, we’ll use Go and Python, but the workflow is nearly identical in other languages.

1. Install the Protocol Buffers Compiler (protoc)

2. Install the gRPC and Protobuf Plugins

  • Go:

    bash
    1go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    2go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    3export PATH="$PATH:$(go env GOPATH)/bin"
  • Python:

    bash
    1pip install grpcio grpcio-tools

3. Write the .proto File

Create a file named user.proto. Write the service and message schema as shown in the example above. This file is the source of truth for both the client and the server.

bash
1📂 project-root/
2 ┣ 📁 proto/
3 ┃ ┗ 📄 user.proto

4. Generate the Source Code

This generated code becomes the bridge between the client, the server, and the protobuf interface.

  • Go:

    bash
    1cd project-root
    2protoc --go_out=. --go-grpc_out=. ./proto/user.proto

    This will produce the files:

    • proto/user.pb.go
    • proto/user_grpc.pb.go
  • Python:

    bash
    1python -m grpc_tools.protoc -I./proto --python_out=. --grpc_python_out=. ./proto/user.proto

Workflow Diagram

To make things clearer, here is a flow diagram (using Mermaid) of the protobuf setup process for gRPC.

MERMAID
graph LR
    A[Tulis file user.proto] --> B[Generate kode dengan protoc]
    B --> C{Client / Server}
    C --> D[Implementasikan logic bisnis spesifik]
    C --> E[Gunakan class/method hasil generate]

Implementation Example: gRPC Server (Go)

Let’s see how the generated file we created earlier is used to build the server:

go
 1// main.go
 2package main
 3
 4import (
 5    "context"
 6    "log"
 7    "net"
 8
 9    pb "project-root/proto"
10    "google.golang.org/grpc"
11)
12
13type server struct {
14    pb.UnimplementedUserServiceServer
15}
16
17func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
18    log.Printf("Received GetUser request for: %s", req.UserId)
19    return &pb.GetUserResponse{
20        UserId:   req.UserId,
21        Username: "johndoe",
22        Email:    "john@example.com",
23    }, nil
24}
25
26func main() {
27    lis, err := net.Listen("tcp", ":50051")
28    if err != nil {
29        log.Fatalf("Failed to listen: %v", err)
30    }
31    grpcServer := grpc.NewServer()
32    pb.RegisterUserServiceServer(grpcServer, &server{})
33    log.Println("Server running at :50051")
34    grpcServer.Serve(lis)
35}

Simulation: gRPC Client (Python)

python
 1# client.py
 2import grpc
 3import proto.user_pb2 as user_pb2
 4import proto.user_pb2_grpc as user_pb2_grpc
 5
 6def run():
 7    with grpc.insecure_channel('localhost:50051') as channel:
 8        stub = user_pb2_grpc.UserServiceStub(channel)
 9        response = stub.GetUser(user_pb2.GetUserRequest(user_id="1234"))
10        print(f"User: {response.username}, Email: {response.email}")
11
12if __name__ == "__main__":
13    run()

A Quick Walkthrough of the Communication Flow

  1. The client builds a request (GetUserRequest) via the stub class (generated code)
  2. That request is serialized by protobuf and sent over the network
  3. The server receives it at the gRPC endpoint and automatically deserializes it through the generated code
  4. The server fills in the response, serializes it again, and sends it back to the client

Table: Mapping .proto to Code

.proto ElementGenerated Go OutputGenerated Python Output
service UserServiceUserServiceServer interfaceUserServiceServicer class
messageGo struct (e.g. GetUserRequest)Python class (GetUserRequest)
rpc GetUserInterface method (Go)Class method (Python)

Pro Tips

  • Use a dedicated folder (/proto, /pb) for your .proto files and generated code to keep the structure tidy.
  • Never edit the generated code by hand — the .proto file is the only thing you should touch.
  • For multi-language projects, store the .proto file in a separate repository as the API contract.

Conclusion

By setting up Protocol Buffers correctly, you’re one step closer to building a gRPC microservice ecosystem that is robust, cross-platform, and blazing fast. Protobuf simplifies maintenance, scaling, and system interoperability. In the next article, we’ll continue by fully implementing a gRPC client and server.

Happy experimenting—and remember, in gRPC, communication is about contracts, not just strings going back and forth.

Related Articles

💬 Comments