Concept · Networking & APIs
REST, gRPC and GraphQL
Three API styles and where each one fits: public APIs, service-to-service, and client-shaped reads.
3 minRPCprotobufAPI styles
Three styles dominate API design. They differ in how operations are described, how data is encoded, and who decides the shape of a response.
| REST (JSON over HTTP) | gRPC | GraphQL | |
|---|---|---|---|
| Model | Resources and HTTP methods | Remote procedure calls defined in .proto files | One endpoint; clients send queries for the fields they want |
| Encoding | JSON (text) | Protocol Buffers (binary) | JSON |
| Contract | OpenAPI (optional) | Required schema, generated client and server code | Required schema |
| Transport | HTTP/1.1 or HTTP/2 | HTTP/2 | HTTP |
| Streaming | Limited (SSE, chunked) | Client, server and bidirectional streams | Subscriptions (usually over WebSockets) |
| Caching | HTTP caches and CDNs work naturally for GETs | Not HTTP-cacheable | Hard to cache at HTTP level (often POST) |
| Browser support | Native | Needs gRPC-Web and a proxy | Native |
Where each fits
- REST for public and partner APIs: universally understood, debuggable with
curl, cacheable, and easy to version. The default when in doubt. - gRPC for service-to-service calls inside your system: compact binary messages, strict contracts with generated clients, deadlines propagated across calls, and streaming. Its tooling assumes you control both ends.
- GraphQL when many different clients (web, iOS, Android) need differently shaped data from many backends. Clients fetch exactly the fields they need in one round trip, avoiding over-fetching and many sequential calls. The costs: query complexity limits are needed to stop expensive queries, caching moves into the client and server layers, and authorisation must be enforced per field.
Design concerns that apply to all three
- Idempotency: retried mutations need idempotency keys.
- Pagination: use cursors, not offsets, for large lists (keyset pagination).
- Evolution: add fields freely; never change the meaning of an existing one. Protobuf field numbers and GraphQL deprecations make this explicit.
- Errors: return a consistent, machine-readable error shape.
The Backend with Go roadmap's REST API design lesson goes deeper on resource modelling and error formats.