gRPC : A quick look
One of the current buzz words in the microservice world is gRPC. Whenever we talk about designing a system or a microservice, the word gRPC will be mentioned at some point. But what is it?
It is an open-source remote procedural call framework designed by google which is really fast.
So that's it. Done. Let us use it.
Nah. I strongly believe that adopting a framework or technology while designing a system or service is not like eating food without worrying about its ingredients.
We must understand why gRPC is faster and I will try to give you a 2-minute quick conceptual overview of it.
Well, many have a perception that gRPC is an alternative to HTTP. They used to do a comparison of gRPC vs HTTP (Even I did at some point, to be honest). But it is not entirely correct to compare gRPC with HTTP because gRPC uses HTTP/2 under the hood.
HTTP/2 has many cool features and it is a much-improved version of HTTP/1.1. But I will be talking about one main feature which I feel is important for gRPC in my book.
Request Multiplexing
In HTTP/2 it is possible to send multiple requests with a single TCP connection in parallel (non-blocking way), unlike HTTP/1.1. In HTTP/1.1 you need to make a TCP connection for each request (as in the image). Off-course you can have keep-alive connections but still, they are blocking in nature i.e at an instant only one request can be processed by a single connection.
But with HTTP/2, you can send and receive N requests and responses in a single TCP connection in parallel which is super useful in the world of gRPC. This solves many problems on both the server-side (like too many open file descriptors) and the client-side (like browser restricting parallel connections to a domain).
Okay, then. If you say HTTP/2 is the secret weapon of gRPC, then what If I switch my existing REST based microservices to HTTP/2, then what is the point of gRPC?
Well, you will benefit from upgrading to HTTP/2. But still, you will end up having the JSON as your payload.
But gRPC uses protocol buffers whose encoding is way more efficient than JSON which makes it really faster. Protocol buffer is another big topic to talk about, but just for the sake of easier understanding, let's think it as a mechanism like JSON which is used to communicate between two services and gRPC uses it as its payload for communication.
For example, if I make a REST request POST /mark with the payload as {"history":100} , then the raw HTTP data will be like below
POST /User HTTP/1.1
Content-Type: application/json
Cache-Control: no-cache
{"history":100}
The same data will be sent to the server and will be parsed based on the provided content type.
Now if you use protocol buffers, the data which will be sent to the server for the above scenario will be 08 64. (The detailed information about how the encoding works can be found here). The difference in the size of a payload for a single gRPC vs REST request may not be a big number. But when you deal with thousands and lakhs of requests the performance difference will be very much noticeable.
In a nutshell
HTTP/2 + Protocol buffers = gRPC. That is the end definition and these are the two main reasons that make gRPC a better candidate than REST.
So now, can we use gRPC?
Well yes, you can. But it entirely depends on the use-case. gRPC will come very handy in building distributed systems and internal microservices. But it too has its pros and cons.
Pros:
- High performance, lightweight and carries the awesome features of HTTP/2 like request multiplexing, full-duplex streaming, etc
- Comes with code generators which makes your life a little easier.
- grpc-web makes it possible now to use gRPC in the browser.
Cons:
- One of the biggest cons which I see in gRPC is the protocol buffer dependency between the server and the client. The client which triggers a gRPC request must have access to the server's Protobuf or at least the code generated by it. This can become really messy when you are developing two microservices that are completely independent. Of course, this can be solved by having a common repo for Protobuf and having it up as a submodule/sub-repo in each microservice repo and generating the code in the CI/CD flow. But still, I see it as a con coming from the REST environment.
I didn't get into the implementation or benchmarking of gRPC in this post. But I will try to cover it up in future posts if possible.
Some useful links:
- https://grpc.io/docs/what-is-grpc/introduction/
- https://developers.google.com/protocol-buffers/docs/encoding
- https://youtu.be/RoXT_Rkg8LA