"REST vs gRPC vs GraphQL"
Choosing an API style: REST, gRPC and GraphQL compared on data format, performance, typing, caching, streaming, browser support, versioning and tooling, with typical uses for public APIs, internal service calls and client-driven data fetching.
Reading is half of it. See this used in a real interview: walk through Design a URL Shortener →
Every design has APIs, and interviewers sometimes ask why you chose REST over gRPC or GraphQL. There is no universally right answer, but there are clear patterns: REST for public and simple APIs, gRPC between internal services, GraphQL when many different clients need flexible views of connected data. Knowing the trade-offs lets you answer in one confident sentence.
REST
Resources identified by URLs, manipulated with HTTP methods (GET /orders/42, POST /orders), usually with JSON bodies.
- Universal: every language, browser, tool and developer understands it.
- HTTP caching works naturally for GET requests, including CDNs. See HTTP caching.
- Human-readable and easy to debug with curl.
- Weaknesses: over-fetching (fields you do not need) and under-fetching (several calls for one screen), loose typing unless you add OpenAPI schemas, and JSON is relatively large and slow to parse.
gRPC
Remote procedure calls defined in Protocol Buffers (rpc GetOrder(GetOrderRequest) returns (Order)), over HTTP/2.
- Compact and fast: binary Protobuf encoding and multiplexed HTTP/2 connections. See serialization formats.
- Strong contracts with generated client and server code in many languages.
- Streaming: server, client and bidirectional streams built in.
- Deadlines and cancellation propagate across calls, which helps with tail latency.
- Weaknesses: browsers cannot call it directly (gRPC-Web or a proxy is needed), harder to inspect by hand, and HTTP caching does not apply.
GraphQL
A single endpoint where the client sends a query describing exactly the fields it wants, across related objects; a schema defines types and resolvers fetch the data.
- No over- or under-fetching: one request returns exactly what a screen needs.
- Strongly typed schema with great tooling and introspection.
- Clients evolve without new endpoints; fields are deprecated rather than versioned.
- Weaknesses: caching is harder (POST to one endpoint; needs persisted queries or client-side caches), expensive or deeply nested queries must be limited, the N+1 resolver problem needs batching (DataLoader-style), and the server is more complex.
Comparison
| REST | gRPC | GraphQL | |
|---|---|---|---|
| Format | JSON (usually) | Protobuf (binary) | JSON |
| Contract | optional (OpenAPI) | required (.proto) | required (schema) |
| Performance | good | best | good, depends on resolvers |
| Browser support | native | via gRPC-Web or a proxy | native |
| HTTP caching | excellent | none | limited |
| Streaming | via SSE or WebSockets | built in | subscriptions |
| Fetching flexibility | fixed per endpoint | fixed per method | client chooses fields |
| Typical use | public APIs, simple CRUD, webhooks | internal service-to-service | client-facing aggregation over many services |
Common combinations
- Public API: REST with OpenAPI, versioned, with API keys and rate limits. See API design.
- Internal microservices: gRPC with Protobuf, deadlines and generated clients. See microservices.
- Mobile and web apps with complex screens: a GraphQL layer (or a backend for frontend) in front of internal gRPC services, aggregating data per screen. See API gateways.
- Real-time: WebSockets or SSE alongside any of these. See WebSockets vs SSE vs long polling.
Large companies often use all three: Netflix and others use GraphQL federation for clients and gRPC internally. See Design Netflix.
Versioning
- REST: additive changes in place, breaking changes under
/v2or a version header. - gRPC: Protobuf field rules (never reuse tags), package versions for breaking changes.
- GraphQL: add fields freely, deprecate old ones, and remove them only when usage is zero (tracked per field).
In the interview
You rarely need to debate this for long. Say: "The public API is REST with JSON because it is cacheable and easy for clients; services talk to each other over gRPC for typed contracts, speed and deadlines." Add GraphQL or a BFF when clients need data from many services per screen, as in Design DoorDash or Design Instagram. For a simple service like Design a URL Shortener, REST alone is fine.
Checklist
- REST for public, simple and cacheable APIs.
- gRPC for internal calls: contracts, performance, streaming, deadlines.
- GraphQL or BFFs when clients need flexible, aggregated data.
- Versioning and compatibility rules per style.
- Query cost limits and batching for GraphQL; gRPC-Web or proxies for browsers.