Blazing fast IPC with gRPC ( Part 2 )

Shobhit Chittora
4 min readJul 22, 2018

--

gRPC in Node

This is a continuation of our learnings from Part 1 of this series. If you landed directly here, I highly recommend you to check it out first.

In this part, we’re going to implement a small Todo app server and client to understand gRPC better. Before we start with the code, it’s better to get an overlay of the land and define what we’re building. This would help us build a mental model of all the moving parts.

The basics

The communication between the client and the server in a typical gRPC ( or any RPC system in general ) is depicted below.

Information flow between the gRPC client and the gRPC server

Both the client and the server implement their own gRPC stubs. These stubs provide the interface to the gRPC runtime and allow for programmatic access to proto messages and services. The RPC runtime is responsible for sending the messages back and forth and also to marshal and un-marshal them.

With this clarity let’s start with implementing our client-server system. We’ll go in the following order —

  1. Init the project, folder structure, and dependencies.
  2. Implement the Todo App’s proto ( messages and service definition ).
  3. Implement the Server ( loading the proto, implementing the service handlers ).
  4. Implement the Client ( loading the proto, initializing the client and making rpc calls ).

Bonus:

Benchmark GRPC and REST servers.

Talk is cheap. Show me the code. — Linus Torvalds.

You can follow up on the code below or checkout the Github repo for the same.

1. Initialize project, folder structures, and dependencies —

Create a new directory and use our old friend npm to initialize a node project. Use —

npm init 

and follow the prompts to initialize the project

Trick : Use `npm init -y` to quickly skip all prompts and use the defaults.

Now go ahead and create a src folder where all our code will exist. Also go ahead and run the following script to install all the package dependencies we will need —

npm i -S grpc @grpc/proto-loader

In addition for quickly starting our client and server, we also add two npm scripts in the scripts object of our package.json created, as below —

“start:server”: “node src/server.js”
“start:client”: “node src/client.js”

Your final package.json file should look something like this —

package.json

2. Define Todo App’s Messages and Services —

Create a file named “todo.proto” in our src folder. We start by giving a package name to our proto and also defining an empty Service.

syntax = "proto3";package todo_app_package;service TodoApp {

}

We then define out Todo message structure —

message Todo {
int32 id = 1;
string name = 2;
bool done = 3;
}

And our Todos message structure which is a collection of all Todos —

message Todos {
repeated Todo todos = 1;
}

We also define a TodoId message which is passed to get the rpc method to get todo by id. We also define an empty Todo payload to request for all todos.

message TodoId {
int32 id = 1;
}
message TodoEmpty {}

Finally, we go ahead and define our rpc(s) for our TodoApp service. The getTodo rpc takes a TodoId message and returns a Todo message. The getAll rpc takes a TodoEmpty message as the request and returns a Todos response message.

3. Mock the db using a json object —

For the sake of brevity of this tutorial, let’s just add a json file which will act as our in-memory database. Create a todos_db.json file under our src folder for the same.

4. Create the server ( loading proto and starting the server ) —

Create a server.js file in the src folder and all the below content to it.

The code above loads the dependencies ( grpc lib and the loader ), and our todos json. Then we create a TodoAppHandler class, the instance of which contains all the rpc methods which our clients can call. We then load the proto using the loader. gRPC provides us with a service instance which can be configured in our server instance to make the rpc work. Finally, bind the service, call the start method on our server and Voila!.

You can then start the server using the script —

npm run start:server 

we added during initialization.

5. Create the client ( loading the proto and making requests ) —

Go ahead and create a client.js file in the src directory and paste the code below into it.

The Client works almost similar to the server. It loads the proto and then binds to the server’s address ( which is hardcode for brevity ). gRPC provides us a Client instance through which we can call the server’s handler methods to get the data exposed.

You can run the client using the below command —

npm run start:client

And just like that, you’ve written a very small but performant gRPC client-server system in Node. Look for the below sections for ideas to do further tinkering.

Next steps

  • Go ahead and implement the other methods such as putTodo which should write a new todo, updateTodo which should update an existing todo and other.
  • Check out the a sample of the streaming api for getAll todos here. Try to understand and convert others to streaming apis as well. Also, think of bi-directional streams.
  • Bonus: Add a front-end to the todo app ( check out Todomvc project for inspiration ).

Thanks for reading through. You can find me at —

Twitter — @shobhitchittora

Github — shobhitchittora

StackOverflow — shobhitchittora

LinkedIn — Shobhit Chittora

--

--

Shobhit Chittora

Full Stack JS Developer @PayPal, ❤️ JS , Open Sorcerer 💻, Seeker 🚀, …