API Design: REST vs gRPC vs GraphQL
REST uses HTTP verbs and JSON over resources, simple, cacheable, and universal, ideal for public APIs. gRPC uses Protocol Buffers over HTTP/2 for fast, strongly-typed, low-latency service-to-service calls with streaming. GraphQL lets clients request exactly the fields they need from one endpoint, avoiding over/under-fetching. Choose by client, performance, and contract needs.
REST: The Default
REST (Representational State Transfer) models the API as resources (/users/123) acted on by HTTP verbs: GET (read), POST (create), PUT/PATCH (update), DELETE. It's stateless, uses standard status codes (200, 201, 400, 404, 429, 500), and typically exchanges JSON. Its ubiquity, human-readability, and native HTTP caching make it the default for public and web APIs.
Good REST design cares about idempotency (GET, PUT, DELETE are idempotent; POST is not, important for safe retries), pagination (cursor over offset for large sets), versioning (/v1/ in the path or via headers), and HATEOAS in theory though rarely in practice. The main weaknesses are over-fetching (getting more fields than needed) and under-fetching (needing multiple round-trips).
gRPC: Fast Service-to-Service
gRPC, built by Google, uses Protocol Buffers (a compact binary serialization) and HTTP/2. You define services and messages in a .proto file, which generates strongly-typed client and server stubs in many languages. Binary encoding plus HTTP/2 multiplexing makes it significantly faster and smaller on the wire than JSON/REST, often cited as several times more efficient.
gRPC supports four call types: unary, server streaming, client streaming, and bidirectional streaming, great for real-time and high-throughput internal microservice communication. Downsides: it's not human-readable, limited browser support (needs gRPC-Web proxy), and harder to debug with curl. It shines for internal east-west traffic, not public-facing APIs.
GraphQL: Client-Driven Queries
GraphQL (created at Facebook, released 2015) exposes a single endpoint and a typed schema. Clients send a query specifying exactly which fields they want, and the server returns precisely that shape, eliminating over- and under-fetching and reducing round-trips for nested data. Ideal for mobile apps and complex UIs with many data shapes.
Tradeoffs: HTTP caching is harder (most queries are POST to one URL), complex queries can be expensive (the N+1 problem, needing DataLoader batching and query cost limits), and the server is more complex. Use GraphQL when many diverse clients consume varied slices of a rich data graph.
| Aspect | REST | gRPC | GraphQL |
|---|---|---|---|
| Format | JSON / text | Protobuf / binary | JSON |
| Transport | HTTP/1.1+ | HTTP/2 | HTTP |
| Typing | Loose (OpenAPI optional) | Strong (.proto) | Strong (schema) |
| Streaming | Limited (SSE/WS) | Native bidirectional | Subscriptions |
| Caching | Easy (HTTP) | Manual | Harder |
| Best for | Public/web APIs | Internal microservices | Flexible client queries |
ResuMax tailors your resume to each role, scores it like a recruiter, and preps you for interviews.
Practice with the interview coachFrequently asked questions
When should I use gRPC instead of REST?
Use gRPC for internal service-to-service communication where low latency, high throughput, strong typing, and streaming matter, like microservices in a backend. Use REST for public APIs, browser clients, and anywhere human-readability, broad tooling, and HTTP caching are priorities.
What problem does GraphQL solve?
GraphQL eliminates over-fetching (receiving unneeded fields) and under-fetching (multiple round-trips for related data) by letting the client request exactly the fields it needs in one query. It's especially useful for mobile and complex UIs consuming a rich data graph.
Why is gRPC faster than REST?
gRPC serializes data as compact binary Protocol Buffers instead of verbose JSON text, and runs over HTTP/2 with multiplexing, header compression, and persistent connections. Smaller payloads and fewer round-trips yield lower latency and higher throughput for internal traffic.
How should I version a REST API?
Common approaches are URI versioning (/v1/users), header versioning (Accept: application/vnd.api.v2+json), or query params. URI versioning is the most common and visible. The key is to avoid breaking existing clients, add fields additively and reserve new versions for breaking changes.