gRPC vs REST — Comparing API architecture
One-size-fits-all does not hold anymore in the world of microservice. In the microservice arena, we divide an extensive monolith system into multiple services with limited scope. All those services are independently deployable. They must communicate with each other in a reliable, consistent and timely fashion.
By breaking a big service into smaller microservices, we increase inter-service communication. At the same time, we should have a mechanism in place to keep the latency in control to give a better consumer experience.
A monolith system is built on inter-process communication, where different services are part of the same deployment, so they communicate via function/method calls. It is free of latency or complexity, which gets induced due to network calls in the case of microservices. In a microservice system, we can broadly classify inter-service communication into two broader categories:
In synchronous communication, the consumer service calls up the producer service in real time. The invoker service’s process is blocked until we get a response from the called-up service. It is suitable for real-time scenarios when a consumer requires data from the producer microservice.
In asynchronous communication, a service invokes an event that can have one or more subscribers and moves ahead with its flow. It is a good tool for designing a near-real system. Moreover, it can sustain a heavy load compared to a real-time approach as the subscriber polls the queue as per its appetite, making it resilient and error-proof.
Comparison between Asynchronous vs Synchronous communication
This article will focus on different types of synchronous communication protocols.
REST (REpresentational State Transfer)
- It should be used for the internet or external-facing microservices.
- It is based on HTTP 1.1/2.0
- It supports document structures like JSON and is suitable for a client call. Here we have a tradeoff of visually viewable payload in place of a minor hit on the performance.
- It is broker less and works on HTTP protocol using HTTP verbs like GET, PUT, POST, DELETE, and PATCH.
- We should adopt the swagger-first approach to maintain a working copy of the REST APIs.
- If we are required to make some changes in the signature of the API (be it payload or the URI), we need to handle the versioning ourselves so that the new changes, in case they are breaking changes, should be published with a new version. Also, we should tag the older version with some predefined deprecation date so that the existing system, whichever is using this, should move to the newer version before that date.
Communication Types in REST
Here client initiates one call to the server, and the server responds with a single response to the client.
Features of REST
Stateless: Rest APIs are stateless. A new server instance can serve a new request for the same session. An API is self-contained and should have all the required information so the server knows what that API is. This helps us in achieving scalability without stickiness.
Uniform Interface: The REST APIs follow common characteristics, making them independent of the implementation. The four standard features are:
- Identifying resources: Rest APIs are identified based on the URI in the request.
- Manipulation through representation: The client should be able to modify or delete the resource based on the resource representation and the associated metadata.
- Self-describing message: The representation of resources should be returned to the client with information about how to consume it.
- HATEOAS: In addition to returning the representation of the resource, it should also return the detailing around how to interact with the resource.
Cacheable: REST APIs are cacheable based on the method type. GET calls are, by default, cacheable, and we can control their cacheable behaviour by header tags. It helps us in achieving performance, server load optimisation & cost optimisation. We can make POST cacheable, but PUT and DELETE do not support caching.
Client-Server: REST APIs are developed using server-side languages like express, spring boot, etc., and the client consumes the APIs created on the server via tools/utilities like postman, cURL, promise, etc.
Layered System: When a client invokes a REST API, it internally might be using different layers to serve another purpose, such as caching by one server, the database might be residing on another layer, authentication and authorisation might be part of another layer and so on. They all being part of the same server or different does not make any difference for the REST API. Moreover, any changes in these internal layers will not impact the REST request or response.
Code on Demand: For most cases, a REST API returns JSON or XML, but we can use it to serve any other format as well, if required.
Use case of REST
Public-facing API: The public-facing APIs should be developed in REST as they are easy to read and expose. REST is a better communication protocol to be used in the public domain.
gRPC (Google Remote Procedure Call)
- gRPC is an open-source RPC developed by Google.
- It is mainly used for backend-to-backend calls (internal calls)
- It is based on HTTP/2.
- It is fast compared to doing communication in REST, but the tradeoff is the payload is not visually readable.
- Communication happens in binary RPC protocol.
- It relies on Protocol Buffers, also known as Protobuf, to define service contracts.
- Protobuf is language agnostic, which means that the producer and the consumer microservice might be in different programming languages working on the same interface defined by Protobuf.
- We define the contract in the Protobuf, and then all the microservice (producer and consumer) can generate their respective client code to enable communication between them.
- gRPC server implements the interface, and the clients have the stub for those interfaces to enable communication between the client and the server.
- gRPC is 30–40% more performant than REST
Communication Types in gRPC
Unary RPCs: Here client initiates one call to the server, and the server responds with one response to the client.
Server Streaming RPC: The client initiates a request, and the server responds with a stream of responses. gRPC guarantees message ordering for a single request.
Client Streaming RPC: The client sends messages to the server. The server receives all the messages in the same sequence as it was sent. Once the client sends all the messages, the server responds with a response.
Bidirectional Streaming RPC: The client sends one or more messages on a stream, and in response to that, the server responds via a different stream with one or more responses. The client and the server can follow their respective pattern to read and write on the streams.
gRPC Benefits
- They are lightweight as compared to REST. Its payload size is 30–40% less than the REST.
- It is 5–8 times faster as compared to REST.
- It has a built-in automatic code generator for a different language, enabling the developers to focus on the business logic and not juggle with the technical complexity of making this work.
- Four types of communication as compared to just one in the case of REST.
Drawbacks of gRPC
- The community is in a growing phase and is currently just supported by the google development team, but with time, its community is expected to grow large.
- As it is built to work on HTTP/2 and the modern browser does not support this, we can’t use it directly with the browser.
- The data payload is in binary format, so it is not human-readable.
- It has step learning curve due to less adoption
Use cases of gRPC
Polyglot architecture: Protobuf can be used as a single point of truth for different microservices. It helps achieve an easy-to-use and self-documented payload that can be used across the domain teams.
Near-real System: It is better for near-real architecture as it reduces the latency between microservice communication in real-time, which helps achieve better SLA around client response time. As it supports bi-directional and uni-directional streaming, we can achieve a better response time even without polling for a few use cases.
Network bandwidth: It works better with low bandwidth as its payload size is smaller than REST, which in turn means better performance with fewer resources.
Cost-effective: It works with less resource consumption, provides better throughput, and is more cost-effective for scaled-up systems.
Conclusion
With microservice and serverless architecture getting more prominent and withstanding their footprint, inter-service communication is increasing, adding to the API call latency.
We should explore gRPC and implement it for all possible inter-service communication where the requirement is to invoke another service synchronously.
It will help us achieve a better customer experience and business goals within the SLA, not just from a performance and scalability perspective but also from a cost perspective.
Resources
- Why is Software Architecture Important?
- The Power of Polyglot Architecture: A Guide for Modern Organisations
- Why Use Microservices — Breaking the Monolith
- AWS SQS, SNS & Event Bridge — When to use what?
- Resilient and high availability in microservices