There are multiples ways to build API. I have already mentioned and describe some of the in different articles.
This text is a kind of One Ring article — one to rule them all. I want you to have a single place where you can find acomparison of all the approaches done in clear and consistent manner. Thus, I have put here all the previouscomparisons, and add some more into this text.
I will compare a total of 7 tools across 10 axes.
Tools:
- REST
- gRPC
- WebSockets
- SSE
- GraphQL
- Webhooks
- Message-Queue Base
Axes:
- Communication Direction
- Underlying protocols
- Message Structure
- Complexity
- Security
- Data size
- Throughput
- Latency
- Ease of adoption
- Tooling
Let’s today’s journey from REST. As it is probably the most common way of building APIs I would use it as a baseline for all the comparison.
Ways To Build API
REST
REST, or Representational State Transfer, is an architecture styles. It uses HTTP as the underlying communication medium thus it is stateless by nature and can benefit from all the advantages of HTTP, like caching. It can utilize both HTTP/1.1, HTTP/2.
Shines when: you need a simple, cache-friendly, web-native API consumed by every language or tool; Struggles when: you need full-duplex streams or extremely low latency.
gRPC
gRPC is probably the most modern implementation of the relatively old concept of — Remote Procedure Call. gRPC uses Google’s Protocol Buffers as a serialization tool. By default, it utilizes HTTP/2 as transport medium data and exchange data in a binary format.
Shines when: services need compact binary messages, strong typing, and bidirectional streaming. Struggles when: you must expose an API directly to browsers without extra tooling.
WebSockets
WebSocket provides bidirectional communication between a server and client with the usage of a single long-lasting TCP connection. Thanks to this feature, the data is exchanged between interested parties in “real-time”. Each message is send as binary frame data or Unicode text. While WebSockets utilize custom protocol for most of the time it is still using HTTP for initial handshake.
Shine when: both client and server need real-time, low-latency push in either direction. Struggle when: intermediaries (CDNs, firewalls) or strict request-response patterns dominate.
SSE
SSE is a technology that allows a web server to send updates to a web page. It is a part of HTML 5 specification and utilizes a single long live HTTP connection to send data in “real-time”. It can use both HTTP/1.1 and HTTP/2. SSE also have its unique MIME type: text/event-stream. The important thing here is that it is can be only used for server-browser communication.
Shines when: the server pushes one-way event streams to browsers with a minimal setup. Struggles when: you need client-to-server push or non-browser consumers.
GraphQL
GraphQL is a query language for your API. It allows clients to request only the subset of data they need. The client knows the server’s endpoint, the endpoint provides a schema. The schema defines the communication protocol, inputs and outputs. The request, is validated with the schema, thus malformed request woulds be rejected by the server with a proper error message.
Shines when:clients must trim over-fetching and compose rich queries from one endpoint. Struggles when: the workload is write-heavy or teams cannot maintain a strict schema discipline.
Webhooks
Webhooks address the question — Has anything changed yet?. It is a push-style HTTP callback that lets another service tell your app when something relevant happens. It works in, in “real” time, no polling, no sockets, just an outbound POST.
Shine when you want lightweight server-to-server notifications without polling.Struggle when delivery guarantees must be exactly-once, or the receiver is offline for long periods.
Message-Queue Base
The message base approach uses a middleware as a way to communicate between services. Usually in form of some platform like Kafka or RabbitMQ. The main idea behind message queues is to provide asynchronous communication. Messages are sent to a queue, which acts as a buffer between the sender and receiver. This decouples the sender and receiver and allows them to operate independently of each other.
Shine when: you need high-throughput, decoupled, async processing with a replay. Struggle when: you require simple, stateless request-response or openly exposed public APIs.
Ways To Build API – Comparison
Below is the most important takeaway from this article. For traits scaled from Very Low to Very High I am using REST a baseline. Thus, for example if one the complexity of the tools is described as Very High you can think of it as far more complex then REST.
Technology | Communication Direction | Underlying Protocols | Message Structure | Complexity | Security² | Data Size | Throughput | Latency | Ease of Adoption | Tooling |
---|---|---|---|---|---|---|---|---|---|---|
REST | Unidirectional | HTTP/1.1 or HTTP/2 | Mostly JSON or XML (text) | Very Low | HTTPS | Large | Moderate | High | Very High | Extensive (Postman, Swagger/OpenAPI, cURL) |
gRPC | Unidirectional or Bi-directional | HTTP/2 | Protocol Buffers (binary) | Moderate | mTLS | Very Small – binary | Very High | Very Low | Moderate but growing | Decent (gRPCurl, Postman) |
WebSockets | Bi-directional | WebSocket (upgrade from HTTP/1.1 or HTTP/2) | Text or binary frames | Low | WSS | Small – binary frames | High | Very Low | Moderate | Good |
SSE (Server-Sent Events) | Unidirectional | HTTP/1.1 | text/event-stream (UTF-8) | Very Low | HTTPS | Moderate – plain text | Moderate | Low | Moderate | Good |
GraphQL | Unidirectional, Bi-directional with subscriptions | HTTP/1.1, HTTP/2; WebSocket for subscriptions | JSON (text) | Moderate | HTTPS | Large | Variable; fewer round-trips | Medium–high | Moderate but rapidly growing | Very Good (Apollo, GraphiQL) |
Webhooks | Unidirectional | HTTP/1.1 or HTTP/2 | JSON, form-encoded, or custom | Low | HTTPS | Large | Depends on event volume (bursty) | Moderate | Very High | Good (ngrok, request-bin) |
Message-Queue | Unidirectional | Kafka TCP, AMQP, MQTT, NATS, … | Binary records, Avro, JSON … | Very High | ACLs, TLS | Small to medium – highly tunable | Very High | Very Low | Low | Extensive |
Summary
There are no good or bad here, nor any silver bullets, it just a couple of tools you can use.
Nonetheless, if you want to know my recommendations here they are:
Scenario / Tech | REST | gRPC | WebSockets | SSE | GraphQL | Webhooks | Message Queue |
---|---|---|---|---|---|---|---|
Mobile → backend | ✓ | ✓ | ✓ | ✓ | |||
IoT / edge device | ✓ | ✓ | ✓ | ||||
Service-To-Service | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
Browser push / live UI | ✓ | ✓ | |||||
3rd integration | ✓ | ✓ | ✓ | ||||
Streaming pipelines | ✓ |
Remember, if you will be building anything more complex then a very focus microservice the odds are that you wil be using more than one approach. Mixing different tools the get the best design is part of our daily struggle (link) just please do not overengineer your solution.
Thank you for your time.