API protocols - REST vs gRPC vs GraphQL vs WebSocket vs Webhooks#
Five different shapes of "service-to-service or client-to-server communication". Each is the right answer for a specific shape of problem.
Side-by-side#
| REST (HTTP/JSON) | gRPC (HTTP/2 + Protobuf) | GraphQL | WebSocket | Webhooks | |
|---|---|---|---|---|---|
| Transport | HTTP/1.1 or 2 | HTTP/2 | HTTP/1.1 (any verb) | TCP upgrade from HTTP | HTTP POST |
| Format | JSON (often) | Protobuf (binary) | JSON over POST | binary or text frames | JSON usually |
| Schema | OpenAPI (optional) | .proto (strict) |
SDL (strict) | none built-in | none |
| Direction | request / response | unary + 4 streaming modes | request / response (with subs) | bidi push | server → client (event-driven) |
| Browser support | native | gRPC-Web (limited) | native | native | server-to-server |
| Versioning | URL / header | protobuf field numbers | additive, no version | application-level | timestamp / id |
| Discoverability | OpenAPI explorer | reflection | GraphiQL | none | OpenAPI for receiving end |
| Strong points | universal, cache-friendly, simple | low-latency service-to-service, streaming, strict types | client-driven shape (no over-fetch) | low-latency push from server | "tell me when X happens" without polling |
| Weak spots | over-fetch / under-fetch, chatty | not browser-native, harder debug | N+1 query trap, complex caching | stateful connections, scaling | retry / idempotency burden on receiver |
Decision tree#
flowchart TB
Q[New API]
Q --> A{Internal<br/>service-to-service?}
A -->|yes, low latency| GRPC[gRPC]
A -->|public / browser| B{Many clients<br/>fetch wildly different shapes?}
B -->|yes| GQL[GraphQL]
B -->|no| REST[REST]
Q --> C{Need server push<br/>to client?}
C -->|push events from server<br/>to another server| WH[Webhooks]
C -->|live updates to browser| WS[WebSocket / SSE]
classDef p fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef s fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
class Q,A,B,C p;
class GRPC,GQL,REST,WH,WS s;
What you'll get asked#
- "Why gRPC over REST for microservices?" → smaller payloads (protobuf), HTTP/2 multiplexing, strict schema, code-gen clients, streaming.
- "Why not gRPC everywhere?" → not native to browsers (gRPC-Web is OK but limited), harder to debug (binary), tooling weaker than REST.
- "GraphQL when?" → many clients (mobile + web + partner) needing different views of the same graph; over-fetching pain on REST. Backend complexity grows: N+1 queries, depth limits, persistent queries.
- "WebSocket vs SSE vs long-poll?" → see Real-time protocols. SSE for one-way; WS for bidi.
- "Webhooks reliability?" → at-least-once with HMAC signing + idempotent receivers + retry / DLQ.
Performance envelopes#
| Protocol | Typical round-trip latency | Payload overhead |
|---|---|---|
| REST/JSON over HTTP/1.1 | 1-5 ms LAN | header + JSON bloat |
| REST/JSON over HTTP/2 | < 2 ms LAN | header compression |
| gRPC | < 1 ms LAN | tiny (protobuf) |
| GraphQL | 1-5 ms + DB joins | medium (JSON) |
| WebSocket frame | µs after open | small |
| Webhook POST | network + receiver | medium |
How they coexist#
A real product usually uses all of them:
- REST for public client + partner APIs.
- gRPC for internal service-to-service.
- GraphQL as a BFF / API Gateway layer in front of microservices.
- WebSocket / SSE for live UI.
- Webhooks for "tell my customer their event fired".
Glossary & fundamentals#
| Tag | Concept | Page |
|---|---|---|
HLD |
HTTP & TLS protocols | http-protocols |
HLD |
Real-time protocols | realtime-protocols |
HLD |
API gateway | api-gateway |
HLD |
API versioning & evolution | api-versioning-evolution |
LLD |
REST API design | rest-api-design |
FAQ#
When should I use gRPC instead of REST?#
Use gRPC for internal service-to-service traffic where strong typing, streaming, and low latency matter. REST stays the right default for public APIs, browser clients, and easy debuggability.
Is GraphQL better than REST?#
GraphQL is better when clients need flexible shape selection and aggregate multiple resources in one round trip. REST is simpler, easier to cache at the edge, and usually wins for resource-oriented APIs.
What is the difference between WebSocket and Server-Sent Events?#
WebSocket is full-duplex and supports binary frames. Server-Sent Events are HTTP-based, server-to-client only, simpler to operate, and survive proxies more reliably. Pick SSE if you only need server push.
When should I use webhooks?#
Use webhooks for outbound event notifications to third-party systems where polling would be wasteful. They suit low-frequency, eventual-consistency flows like billing receipts and CRM sync.
Can I expose gRPC to browsers?#
Not directly. Browsers cannot speak HTTP/2 gRPC framing. Use gRPC-Web with a proxy like Envoy that translates between gRPC and browser-compatible HTTP/1.1 or HTTP/2 with grpc-web framing.
Further reading#
- 📑 Docs - gRPC - official documentation
- 📑 Docs - GraphQL - official site + spec
- 📑 Docs - REST API Tutorial - Roy Fielding's REST primer
- 📑 Docs - Google AIPs - API design guidelines
- 📖 Book - JJ Geewax - API Design Patterns
- 📘 Book - Roy Fielding - REST dissertation