Introduction to gRPC with Golang

GRPC Go

Here, we will learn everything about what gRPC is and how we can implement it with the Go programming language. Be sure to have a notebook or text editor ready to take notes for future reference. Also, go through some of the other tutorials on this website if you’re interested.

Why gRPC?

Today, applications are written in a variety of languages – one for the frontend, another for the database, yet another for the backend, a different one for an Android app, and a different one for iOS. So, it is evident that they all need to communicate with each other. And to do this, they all need to abide by a singular set of API contracts:

  • the communication channel
  • authentication
  • payload format
  • data model
  • error handling

All these must be efficient (light and fast) and simple. And we do all these using gRPC.

What is gRPC?

It’s a high-performance open-source feature-rich framework originally developed by Google and now is a part of the Cloud Native Computing Foundation (or CNCF) just like Kubernetes or Prometheus.

RPC stands for Remote Procedure Calls, whereas the g doesn’t stand for Google. Instead, it has changed between good, green, and glorious, game, gon, etc (I know…I know…).

It’s a protocol that allows a program to execute a procedure of another program located in another computer. The best thing is that developers don’t have to explicitly code the details of the network interaction, and it’s automatically handled by the underlying framework. So in the client code, it looks like we are just calling a function of the server code directly. And it works even if the codes on the client and server are written in different programming languages.

How it works is that the client has a stub that provides the same method or function as the server. The stub is automatically generated for you by gRPC. The stub will call the gRPC framework under the hood to exchange information with the server over the network.

Thanks to the stub, the client and server now only need to care about implementing their core services’ logic. We will see how the gRPC stubs are generated with the help of protocol buffer in further articles.

Code generation by gRPC

Code generation is one of the most important features of gRPC. In order to generate stubs for the server and client, we first need to write the API contract which includes a description of the services and their payload messages in a protocol buffer file (it has a .proto extension).

syntax = 'proto3';

message HelloRequest (
    string name = 1;
)

message HelloResponse (
    string greet = 1;
)

service Welcome (
rpc Hello(HelloRequest) returns (HelloResponse);
)

From this proto file, the server and client stub codes are generated by the protocol buffer compiler (or protoc). The generated code for Go will be something like this:

//Go code
...

type HelloRequest struct {
     Name string
}

type HelloResponse struct {
     Greet string
}

type WelcomeServiceClient interface {
     Hello(*HelloRequest) (*HelloResponse, error)
}

type WelcomeServiceServer interface {
     Hello(*HelloRequest) (*HelloResponse, error)
}

It represents data in binary format which is smaller size and faster to transport. It is also more efficient to serialize than some text-based formats like JSON or XML. It provides a strong-type API contract between client and server, which is super safe to work with. And it has a great set of rules for API evolution to ensure a backward and forward compatibility.

Multiplexing is also possible in HTTP/2 (the transfer protocol that grpc uses) which means the client and server can send multiple requests and responses in parallel over a single TCP connection. This will help reduce the latency and improve network utilization.

Types of gRPC

There are 4 types of gRPC:

  • The simplest one is unary – Where the client sends 1 single request message and the server replies with 1 single response
  • client streaming – Where the client will send a stream of multiple messages and it expects the server to send back only 1 single response
  • server streaming – Where the client sends only 1 request message and the server replies with a stream of multiple messages
  • bi-directional or bidi streaming – Where the client and the server will keep sending and receiving multiple messages in parallel and with arbitrary order. It’s very flexible and no blocking, which means, no sides need to wait for the response before sending the next message.

This differentiates it from a service like REST, where only a 1-way request from the client to server is allowed. However, while REST is fully supported by all browsers, the support for gRPC is limited.

The main use of gRPC is the implementation of microservices. (Microservices are generally also seen in some video games, where it is possible to purchase special clothes and accessories for your game character inside the game.)

Since gRPC enables low-latency and high-speed communication, as well as strong API contracts, it is ideal for such fast, secure transactions.

In the next segment, we shall see how to implement a unary gRPC and much more. So check out Unary gRPC with Golang – Part 2.

References