KYC: Know your (Client-Server) Communications! REST vs GraphQL vs gRPC vs WebSocket
Coffee with System Design #1
Ever wondered if there's just one way how micro-services communicate with each other or if the UI could only make REST calls to the backend services or even if there's a better way to go about these for your particular use case?
Well, this article is to elaborate on the various modes of communication that exists today between a client and a server, be it between the UI, backend services, message brokers, databases, etc.
Each of these modes "attempts" to solve a particular problem and so is made for a particular use-case in mind. "Attempts" because an ideal solution is a myth! Software engineering is not as simple as one might think! There's a sort of barter that's always involved - give and take! And hence, which approach you'd wanna take up depends on "how much of what" are you willing to trade. I'll discuss them all here.
Here we go.
1. REST
The most commonly used (and therefore not going to elaborate on what it is) mode of communication are the REST APIs.
In my simple words, it's a set of architectural constraints (but not a protocol) that effectively translates to it being a communication technique where each "message" (request) has all the info (token, payload, caching info, etc) it needs to retrieve or produce a result (response).
PROs:
- Flexible AF! Depending on the request, the same resource (URI) can be fetched in different data formats (JSON, XML, etc), the same URI for different operations (HTTP methods), HATEOS, layered structure, etc.
- Scalable! Since its stateless (thus separating client and server), multiple instances of a server would produce the same outcome for the same request.
- Uniformity! Universality! Doesn't require the client to be aware of method names, etc. Only need to know a URI.
CONs:
- Although it does what it says, the HTTP is a synchronous client-initiated request/response model, and as such is sort of uni-directional and also tends to be "chatty".
- Bi-directional communication doesn't fit in naturally, the way WebSockets do. WebHooks are just a hacky way to go about it.
- Over or under fetching of data as the queried data structure (schema?) is predefined by the server.
When to use:
- Limited bandwidth and resources.
- Ease of coding is a requirement. (Although each API needs to be coded separately)
- Caching is a requirement.
- Not meant for streaming communication.
- Not meant for bi-directional communication.
2. GraphQL
The complexity of data requirements are ever increasing. REST finds itself in short to keep up with the speed of changes required in the data, along with the growing need for iterations and expectations for rapid feature development. And thus, enter GraphQL! (Thanks Facebook or now as you call yourselves - "Meta"!)
PROs:
- A single endpoint and a single HTTP verb (POST). The client has more power on what it wants by specifying it in the request payload.
- Precise fetching of data makes efficient use of the limited bandwidth.
- Development speed is quite rapid, and since its client driven, any change in requirement is mostly a change on the client side to change their query for data.
- FASTER! Because a single network call can accommodate all the data GraphQL provides, in contrast to multiple calls for RESTful services.
CONs:
- Complex queries (w/ too many nested fields) in GraphQL raises concerns on backend performance.
- Complicated caching since it makes use of a single URL.
- Complicated rate-limiting.
When to use:
- Rapid changing of data requirements? Consider GraphQL!
- When the clients need to dynamically iterate and design data as per their need, thereby making efficient use of limited bandwidth.
- Caching, rate-limiting, monitoring is not a requirement.
- Not meant for streaming communication.
- Not meant for bi-directional communication.
3. gRPC
Another approach growing in popularity (due to its high speed in binary communication) is the Google's Remote Procedure Call APIs - gRPC. It uses HTTP /2.0 under the hood.
The client directly calls a "procedure"/"method" in the server application running on a different machine as if it were a local to the client application.
As in many RPC systems, gRPC is based around the idea of defining a service, specifying the methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub (referred to as just a client in some languages) that provides the same methods as the server.
Benchmark reference: https://github.com/david-cao/gRPCBenchmarks
PROs:
- Super low latency! Lowest so far! Up to 10 times more performant than REST.
- Allows bi-directional and streaming communication.
CONs:
- gRPC must be incorporated into both the client and the server.
- HTTP APIs are often proxied to add security features, perform input validation, map data formats, and solve many other problems. This is not possible with gRPC.
- Since HTTP allows for consistency using Etags in headers, this however is not possible with gRPC.
When to use:
- Mainly used for communication between internal/private systems.
- Real-time streaming applications and IOT applications.
4. WebSocket
WebSocket is a communication protocol which features bi-directional, full-duplex communication over a persistent TCP connection.
There is limited HTTP overhead (like headers, cookies, etc.) making data transfers possible at a much higher rate.
PROs:
- Bi-directional Full-duplex!
- High transmission rate!
CONs:
- Unreliable: Unlike HTTP, Web socket connections can be unreliable due to connection issues. In real world scenarios, it’s always good to have a solution in place to recover any lost messages.
- Load balancing issues: Unlike HTTP servers where horizontal scaling is possible, there is no standard way to scale web socket servers. This is because each client needs a persistent connection with one server to communicate. There are custom implementations such as N-CHAN that allows you to overcome this problem.
When to use:
- When there is a need for to-and/or-fro transmission of data at a HIGH rate.
- Chat applications, games, etc.
Honourable Mentions:
- SOAP : It was the big boss predominantly used for obtaining data from database, until REST stepped in.
- WebTransport : It is a new protocol that has been introduced to fill the gaps between HTTP/2, Websockets and UDP like connections. It also that allows web applications to establish interactive, bidirectional, multiplexed network connections. WebTransport has the compatibility with HTTP3 and it is proposed to be compatible with QUIC protocol. It can offer standardized live communications over different versions of HTTP Protocols.
End of Chapter!
Thanks for reading!