If you are looking for a practical implementation tutorial, here’s the link to my next article — A simple tutorial on “How to implement a simple gRPC service using Golang”
Getting started — Understanding RPC
What is RPC?
- RPC aka Remote Procedure Calls — are just like functions.
- These functions are executed on some remote system and hence the name.
- It follows a request — response model.
- A request is initiated from the client — this request is a function call with certain parameters and then, the server returns a response.
- Real world application — to construct distributed, scalable, client — server based applications.
gRPC
- gRPC is a technology to implement RPC APIs.
- Can write servers and clients using different programming languages — a client written using Python can interact with a server written in Golang.
- By default gRPC uses protocol buffers as the interface definition language (IDL) to define the RPC services and the structure of the payload messages
Further reading — gRPC Documentation
Understanding protocol buffers and .proto files
What is protobuf?
- Protocol buffers are a way to serialize structured data in an efficient manner.
- It uses the method of binary serialization, which is faster than text based serialization methods like JSON.
- The protobuf specification can be implemented in various programming languages.
What is a .proto file
A .proto file will contain the necessary definitions to see the protocol buffers in action.
A file with .proto extension will contain the definitions of messages and services. The services are analogous to procedures/functions and the messages are analogous to the data types of the parameters that can be passed to these functions.
syntax = "proto3";message UrlRequest{
string req = 1;
}message UrlResponse{
int res = 1;
}service Url{
rpc CallUrl(UrlRequest) returns (UrlResponse){}
}
In the above example, the first line of the file specifies that you’re using proto3
syntax, CallUrl
is a service, UrlRequest
and UrlResponse
are the message definitions. We can see that the CallUrl
acts as a function with input parameter as UrlRequest
and output as UrlResponse
. The message definitions can have fields within them. Each field has a name and a type. Here we have a req field which has the data type string in UrlRequest
and res is a field whose data type is int in UrlResponse
.
Important step — Compiling a .proto file
- This generates helper code to implement the server and client code in the programming language of your choice.
- The generated code also handles the parsing of structured data as the data is serialised into a binary format which can be transferred more efficiently as compared to text based serialisation methods like JSON, XML.
Further Reading — Language Guide (proto3)
Let’s Code — Basic Workflow
- Define the protocol — Write a .proto file.
- Define messages with respective fields.
- Define RPC service procedures with their respective parameters and return types. There can be 4 types of RPC procedures: simple RPC, server-side streaming RPC, client-side streaming RPC, bidirectional streaming RPC.
- Compile .proto file — generates protobuf related code for binary serialization of data; also generates client and server stubs.
- Write Server and Client code using language of your choice with the help of the generated stubs — gPRC currently supports the following languages — C# | C++ | Dart | Go | Java | Kotlin | Node | Objective-C | PHP | Python | Ruby .
- Compile and run the final application.