Introduction to gRPC

Introduction to gRPC


If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched article every week delivered straight to your inbox.


Today, there are different popular API architectural styles available. For example REST, SOAP, RPC(Remote Procedure Call), GraphQL, etc. Each API architecture style defines the principles of how the different services should communicate using the APIs, how the data exchange must happen, how API error handling must be done, etc.

What is gRPC?

gRPC is an open-source, cross-platform, high-performance Remote Procedure Call (RPC) framework developed by Google. By cross-platform, I meant that it’s not dependent on any single language. It can help you easily generate boilerplate code and help you do fast development for your microservices architecture.

gRPC is built on top of the HTTP/2 communication protocol and uses Protocol buffers(with file extension .proto) for data transfer. The protocol buffers take a small size in data transfer making them fast for data transmission on the network.

In gRPC, a client application can directly call an API of a server application on a different machine as if the client’s application was merely calling another function, making it easier for you to create distributed applications.

For example: in the below image, you can see that the server code is written in C++ and has a gRPC server associated with it. Different clients written in different languages have a gRPC stub and can connect with the server using the proto buffers request and get proto buffers response in return.


Article content
Representation of a gRPC framework using server and clients

Protocol Buffers

When you would have used the REST API style to build your APIs, you most likely used JSON or XML to transfer the data over the network. JSON or XML formats are human-readable formats.

In gRPC, Protocol buffers(commonly called "protobufs") are the data exchange mechanism between the client and the server. Protocol Buffers serialize data in a binary format, making it more compact and faster to parse than human-readable formats like JSON or XML. That’s why, gRPC is such a popular framework to build microservices because of fast & light data transfer over the network.


Article content
Data exchange in REST vs gRPC API styles

Build a Golang App using gRPC

Alright, enough about theory. I did one practical example and built a client-server app in Golang using the gRPC framework. I suggest you do the same. This will help you visualize the true power of the gRPC framework. Here are the steps in the Golang:

Step 1: Install the protocol buffer compilers and the extra plugins that are required to generate the automated code using the proto files.

brew install protobuf
protoc --version

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

Refer to this guide for protocol buffer compiler installation.

Step 2: Create a directory, move into it, and initialize it as a go module

mkdir my-go-app
cd my-go-app
go mod init my-go-app        

Step 3: Go language install libraries to a bin folder. You need to add the bin folder in the PATH environment so that the protobuf compiler can create the generated files. For example:

export PATH="$PATH:$GOPATH/bin/"
source ~/.zshrc        

Step 4: Create the greeting.proto file inside the my-go-app/proto folder.

syntax = "proto3";

option go_package = "./proto";

package greeting;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
    string name = 1;
}

message HelloResponse {
    string message = 1;
}        

Step 5: Run this command to create the generated files.

protoc --go_out=. --go-grpc_out=. proto/greeting.proto        

This command would generate the files: greeting.pb.go and greeting_grpc.pb.go. These files contain the boilerplate code for the client and the server interaction.

Step 6: Create the Client and the server files.

server.go

package main

import (
    "context"
    "fmt"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "my-go-app/proto"
)

// Server implements the Greeter service defined in the .proto file.
type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello implements the SayHello RPC method.
func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
    message := fmt.Sprintf("Hello, %s!", req.GetName())
    return &pb.HelloResponse{Message: message}, nil
}

func main() {
    // Set up a TCP listener on port 1234
    lis, err := net.Listen("tcp", ":1234")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    // Create a new gRPC server
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})

    log.Println("gRPC server is running on port 1234")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}        

client.go

package main

import (
    "context"
    "log"
    "time"

    "google.golang.org/grpc"
    pb "my-go-app/proto"
)

func main() {
    // Set up a connection to the server
    conn, err := grpc.Dial("localhost:1234", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    client := pb.NewGreeterClient(conn)

    // Make a request to the server
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    response, err := client.SayHello(ctx, &pb.HelloRequest{Name: "Vivek"})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }

    log.Printf("Client received: %s", response.GetMessage())
}        

Step 7: Run the server.go and the client.go and see the magic yourself.

go run server.go
-- Output
2024/11/02 09:30:27 gRPC server is running on port 1234

go run client.go
-- Output
2024/11/02 09:30:31 Client received: Hello, Vivek!        

Takeaways

Now that you’ve built a full-fledged client-server using Golang, you can observe the following points about using the gRPC framework:

  1. Did you notice how greeting.proto defines an API contract which is important for all clients to communicate with the server? The proto files act as the single source of truth for client-server communication.
  2. The proto file is written generically and not constrained to any particular language.
  3. In this example, we used the client and server both in Golang, but that does not demonstrate the gRPC framework’s full power. You can create your server in C++ using a similar proto file and host it in a different repository. Similarly, you can create a client in Java and mention the C++ service’s proto file as the dependency (just like other language dependencies) and use it for calling the server.


That’s it, folks for this edition of the newsletter. I hope you liked this edition. I will continue to write more about gRPC and Golang in the future editions.

Please consider liking 👍 and sharing with your friends as it motivates me to bring you good content for free. If you think I am doing a decent job, share this article in a nice summary with your network. Connect with me on Linkedin or Twitter for more technical posts in the future!

Curious Engineer is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.

Resources

Introduction to gRPC

What are protocol buffers?

Protocol Buffers Basics Go

gRPC basics tutorial in Golang


Sahil wahi

Software engineer 2 @Amazon || 15k+ on Linkedin|| Ex Software engineer @Indmoney, Sprinklr||Ex Software Engineering intern @Phenom

11mo

Nice explanation on gRPC and how data serialisation is an important part of network communication Here i have also explained different serialization processes https://www.linkedin.com/posts/sahil-wahi-2a947b1a9_part-2-for-covering-designing-data-intensive-activity-7227936420282167296-k1ck?utm_source=share&utm_medium=member_desktop

Like
Reply
Aman Mehta

Engineering @ Zepto | Ex - Naukri.com, IndiaMart | Java | Spring Boot | GoLang | PHP

11mo

Insightful 🫡

Like
Reply
Kartik Kaushik

Full Stack developer | content creator| open for collabs| freelancer

11mo

nice share Vivek Bansal

Like
Reply
Aditya Soni

Data | Software & Machine Learning Engineering | Kaggle Competitions Master

11mo

Awesome! It's an amazing concept for sure!

Like
Reply
Ian Zagorskikh

Senior C++ Engineer | Real-Time Streaming & Network Systems | WebRTC / HLS / CDN / Embedded Linux

11mo

In its time CORBA was quite popular. It also has binary serialization on wire, Interface Definition Language (IDL) and stub generator, several open-source implementations and all that. Very promising thing. Until you get into debugging its generated boilerplate of course.

Like
Reply

To view or add a comment, sign in

More articles by Vivek Bansal

  • How to implement a Circuit Breaker

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    7 Comments
  • How to implement Consistent Hashing

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    3 Comments
  • Optimistic Locking Implementation

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

  • 1 year to Curious Engineer 🎉

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

  • Message Queues vs Message Brokers

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    4 Comments
  • Non-Functional Requirements

    Brief Introduction Let’s say you are building a website that allows users to book flight tickets. The requirements for…

    4 Comments
  • QuadTrees

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    2 Comments
  • Text Based Search: ElasticSearch

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    3 Comments
  • Sharding vs Partitioning

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    5 Comments
  • SkipList: A probabilistic data structure

    If you like the free content I put out, consider subscribing to my newsletter on substack to get a well-researched…

    9 Comments

Others also viewed

Explore content categories