How it works
The explanation, with examples you can run.
Side by side
| REST | GraphQL | gRPC | |
|---|---|---|---|
| Contract | Optional (OpenAPI) | Required schema, introspectable | Required .proto files |
| Who shapes the response | Server, per endpoint | Client, per query | Server, per method |
| Round trips for related data | Often several | Usually one | One per call; you design the methods |
| HTTP caching | Natural, by URL | Needs GET plus persisted queries | Not used |
| Errors | HTTP status codes | errors array, often with HTTP 200 | Status codes in the gRPC protocol |
| Streaming | SSE, WebSocket alongside | Subscriptions | Built in, both directions |
| Browser support | Native | Native (it is HTTP plus JSON) | Needs gRPC-Web or a proxy |
| Server-side risk | Endpoint does known work | Client chooses the work: needs cost limits | Method does known work |
| Evolution | Versions or careful additions | Add fields, deprecate, measure usage | Add fields by number, never reuse numbers |
When each fits
REST is a good default for public APIs, simple CRUD, file uploads and downloads, webhooks, and anything that benefits from CDN caching. Every tool, proxy and developer understands it.
GraphQL pays off when many different clients (web, iOS, Android, partners) need different views of the same connected data, when screens combine many resources, and when the frontend changes faster than the backend. It costs you a query engine to secure: cost limits, field-level authorisation, batching to avoid N+1, and caching that lives in clients and data loaders rather than URLs.
gRPC suits internal service-to-service calls: low latency, high volume, strict typed contracts with generated clients in many languages, and streaming both ways. It is awkward for browsers and for ad hoc exploration with everyday tools.
Combining them
A common shape: services talk gRPC (or REST) to each other; a GraphQL layer, a single server or a federated graph, sits in front of them as the backend for frontends; and a small REST surface handles public, cacheable or callback endpoints. The GraphQL resolvers become thin adapters calling the services underneath, which is also where DataLoader batching turns a graph of field requests into a few efficient service calls.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.