Blazing fast IPC with gRPC ( Part 1 )

Shobhit Chittora
6 min readJul 22, 2018

--

Image from https://grpc.io/

You probably have heard of this cool kid around the block, who has been knocking people’s socks off since Roy Fielding wrote his paper in the year 2000. REST has taken over the world since and there hasn’t been any serious competition. The philosophies of the REST architecture inspired several innovations around the tech industry and it has become a de-facto standard for developer APIs and service interactions. Specifications such as OpenAPI / Swagger and GraphQL are clear successors of the RESTful wave and have revolutionized the way we expose data to our consumers.

With such great adoption of REST for exposing our client APIs, and with the advent of microservice architecture, it’s common to transfer the same learnings and implement our inter-service communication ( a.k.a. IPC ) using REST. While REST worked fine for monoliths with advantages like — human readability, easy testing and loose coupling between client and server, it sure lags behind in microservice architectures where you have stateless instances and chatty interfaces. Some of the major disadvantages of using REST for inter-service interactions can be —

  1. Maintaining API contracts is difficult ( though OpenAPI solves it up to a certain limit, but more on this later ).
  2. JSON is hard on the wire and on the CPU, as it’s designed to be human readable and sent as plain text over the wire.
  3. Streaming is fundamentally difficult with HTTP/1.1.

So as an alternative, many companies have had their own internal tooling for inter-service communication ( bet it HTTP based or not ). This scenario of one service calling some other service is called IPC or Inter-Process Communication. A special case of IPC is Remote Procedure Call or RPC in short, in which a method inside a service can call another method which might reside insider some other service ( probably in a different address space or on a different physical machine ), just like any other local method.

Keep in mind all the context from above, let’s see what is gRPC and how it can solve some of the problems with REST mentioned above and also give us awesome features out of the box.

What is gRPC?

gRPC is an open source RPC framework by Google. It is designed to be highly performant and implemented across many environments and languages.

The major selling point of gRPC is its speed and the ability to implement polyglot services in a microservice style architecture. You can also use it to connect mobile and browser clients to your servers. Other benefits include bi-directional streaming through HTTP/2 and pluggable load balancing, auth and monitoring.

gRPC Motivation and Design Principles.

Like most of the major tech companies out there, Google has long been using microservices architecture for running most of its services. And as a result of this, they had a common RPC framework called Stubby to connect their microservices distributed across data centers. Having all the services implement a common framework allowed for things like easy monitoring, faster iterations, security and reliability among others.

However Stubby was not general purpose and there was too much of Google in it ( pun intended 😛). Feeling a need to evolve Stubby and considering its tight coupling with Google’s infra, the team decided to spin off a new project aimed at achieving all thing Stubby could do but also keeping an open and general design. They even went ahead and took inspiration from other widely standardized projects such as SPDY, HTTP/2, and others.

For more on the design principles behind gRPC read the official page.

So why should you care?

So far we’ve discussed the pros and cons of REST. Now let’s see what gRPC is packing for the face-off.

  1. Static Typed and Versioned Interface — gRPC uses an IDL ( Interface Definition Language ) called Protocol Buffer to define rpc services and their request and response models. Protocol Buffers come with a type system, thus allowing us to structure the types of our messages and allow for compile time detection of type mismatches. Also, versioning API becomes easy as the addition or deletion of keys to our request and response models do not break existing client implementations. In the sections to come, we’ll discuss Protocol Buffers in much more detail.
  2. Efficiency and stability — By default Protocol Buffers are designed to be efficient on the wire. This allows for faster data transfers between services. The call and wait model with REST is challenged by the streaming model thus providing better stability of the systems. The very nature of a typed system and backward-compatible model allows for solid stability.
  3. Polyglot services — Having an IDL and client-server stubs across many languages, allows gRPC users to go the polyglot way and choose different languages for different microservices.
  4. Timeouts and request cancellation — gRPC provides out the box solution for request cancellation and timeouts for services. Each call can carry timeout fields which are then used to calculate the new timeouts as request propagates down our microservice stack.
  5. Logging and metrics — gRPC provides easy extensions to plug logging and monitoring systems such as Zipkin.
  6. Bi-directional side streaming — With HTTP/2 support we get features like streams which allows for a non-blocking I/O model for requests and response. This is not the case in the REST world where there the request blocks some resources until the data is aggregated for the response.Also with gRPC we get bi-directional streaming, thus allowing for a better model to transfer data than the chatty RESTful APIs.

What it won’t solve for you?

Well, gRPC won’t just make your API designs better. You can still write badly designed gRPC endpoints and get away with it. The design of API if considered an implementation detail in gRPC world and thus is left for the implementors. So think twice before writing your APIs.

What are Protocol Buffers?

Protocol Buffer is a high performance, open source binary serialization protocol that allows for easy definition of services and automatic generation of client libraries. Similar to gRPC, Protocol Buffer compilers are available in many popular languages and platforms.

Compared to other data exchange formats such as XML and JSON, Protocol Buffers and much more faster, light-weight, simpler and clearer. They provide features to compile data from various sources and update structures with breaking the old compiled structures.

Protocol Buffers example

While writing structures in Protocol Buffer format, we define messages which are the units of encapsulation here. The messages are the serialized over the wire and de-serialized a the other end. Consider the sample below -

Some things to notice about the proto messages are -

  1. Each field in a message has a type ( string, int32, bool or even other message types ). This allows for the type system to enforce static type checking during compilation.
  2. Each field also has a unique numbered key associated with it. The keys are an integral part of the encoding scheme of messages.
  3. Fields can also be marked as required, optional or repeated.
  4. You can run the compiler to get language specific accessor/stub classes. Through them, you get getter and setter methods to read and write messages.
  5. Also updating ( adding or removing ) fields to a message do not break old binaries. The new fields are just ignored by older binaries. Win win !

For more on the Protocol Buffers language specification check the proto3 spec.

Further Reading

  1. gRPC docs
  2. gRPC Load Balancing
  3. Intro to gRPC: A Modern Toolkit for Microservice Communication
  4. gRPC vs REST: let the battle begin! by Alex Borysov & Mykyta Protsenko

Stay tuned and check out the Part 2 where we implement a gRPC Todo App in NodeJS.

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 🚀, …