REST vs GraphQL vs gRPC for App Backends
Every app needs a way for its front end to talk to its backend, and there are three dominant styles: REST, GraphQL, and gRPC. They're often argued about as if one is simply "modern" and the others "legacy," but that framing is wrong — each solves a different problem well. This post compares them plainly so you can pick with intent.
REST: the dependable default
REST models your API as resources (users, orders, expenses) accessed over standard HTTP verbs: GET to read, POST to create, PUT/PATCH to update, DELETE to remove. A request to GET /users/42 returns that user as JSON.
Strengths:
- Universally understood. Every developer, tool, and platform speaks REST. Onboarding is trivial.
- Works with the web's plumbing. HTTP caching, status codes, and proxies just work.
- Simple to build and debug. You can hit an endpoint from a browser or
curland see exactly what happens.
Weaknesses:
- Over- and under-fetching. An endpoint returns a fixed shape. You often get more data than you need, or have to make several calls to assemble one screen.
- Endpoint sprawl. Complex apps accumulate many specialized endpoints.
Best for: most apps, most of the time. If you're unsure, start with REST — it's the lowest-risk choice and it's rarely the wrong one.
GraphQL: the client asks for exactly what it needs
GraphQL exposes a single endpoint and a schema describing all available data. The client sends a query specifying precisely which fields it wants, and gets back exactly that shape — no more, no less.
query {
user(id: 42) { name, expenses(last: 5) { amount } }
}
Strengths:
- No over/under-fetching. The client requests one tailored payload for a whole screen, even across related data.
- One request for complex screens. Great when a view needs data from several sources at once.
- Strong typing and introspection. The schema documents itself and powers excellent tooling.
Weaknesses:
- More server complexity. You implement resolvers and must think about performance (the classic "N+1 query" problem) and query cost limits.
- HTTP caching is harder than with REST, since everything goes through one endpoint.
Best for: apps with rich, interrelated data and many client screens that each need different slices of it — and teams willing to invest in the extra server-side machinery.
gRPC: fast, typed service-to-service calls
gRPC uses a compact binary format (Protocol Buffers) over HTTP/2. You define your service and messages in a .proto file, and it generates strongly-typed client and server code for you. Calls look like normal function calls.
Strengths:
- Performance. The binary protocol is smaller and faster to serialize than JSON — meaningful at high volume.
- Strong contracts. The
.protofile is the single source of truth; client and server can't drift. - Streaming. First-class support for streaming data in either direction.
Weaknesses:
- Not browser-friendly. Browsers can't call gRPC directly without a proxy layer, which limits its use for public web/mobile clients.
- Less human-readable. Binary payloads are harder to inspect and debug than JSON.
Best for: internal, service-to-service communication in a microservices backend, where performance and strict contracts matter and both ends are yours.
How to choose
- Building a typical app backend, or unsure? → REST. Boring is a feature.
- Do your clients need flexible, tailored data for many different screens? → GraphQL.
- Are you connecting internal services and need speed and tight contracts? → gRPC.
And note they aren't mutually exclusive. A very common architecture: REST or GraphQL at the edge (what your app talks to) and gRPC between internal services behind it. Each layer uses the tool suited to its job.
Summary
REST, GraphQL, and gRPC aren't a ranking — they're a toolbox. REST is the simple, universal default and the right call for most apps. GraphQL shines when clients need flexible, precisely-shaped data across many screens. gRPC excels at fast, strongly-typed communication between your own services. Choose based on who's calling the API and what they need, start with REST unless you have a concrete reason not to, and remember you can mix them where it makes sense.