Welcome back! Once you know what an API is, a new question appears fast: REST, GraphQL, or gRPC — which one should you use? Good news: each has a clear personality, and by the end of this post you'll have a simple rule of thumb.
REST: the friendly default
REST organizes an API around resources (nouns like
/orders/42) and standard HTTP verbs (GET, POST,
PUT, DELETE). We covered it thoroughly in
REST APIs explained with a pizza shop.
- Where it shines: it's everywhere. Every language, tool, and browser speaks it; responses cache beautifully; you can explore an API with nothing but a URL.
- Watch out for: over-fetching and under-fetching. The server decides the shape of each response — so you might get fifty fields when you needed two, or need three round trips to gather one screen's worth of data.
GraphQL: ask for exactly what you want
GraphQL flips the arrangement. Instead of many URLs, there's one endpoint, and the client sends a query describing exactly the fields it wants — no more, no less:
{
order(id: 42) {
status
pizzas {
name
size
}
}
}
The response mirrors the query's shape: just status and a list of pizzas with
name and size. It's like handing the kitchen a precise shopping
list instead of accepting a fixed combo meal.
- Where it shines: complex UIs with many different screens — and many different clients (web, mobile, watch) each needing different slices of the same data. One flexible endpoint replaces a pile of custom ones.
- Watch out for: server-side complexity. Someone must build and maintain
the schema and resolvers, guard against expensive runaway queries, and rethink caching,
since every request is a
POSTto the same URL.
gRPC: the fast internal courier
gRPC is built for speed between services. It's contract-first: you define your operations and message shapes in a protobuf file, and tooling generates client and server code in your language of choice.
service OrderService {
rpc GetOrder (OrderRequest) returns (OrderReply);
}
message OrderRequest {
int32 id = 1;
}
Instead of readable text, messages travel as compact binary — dramatically smaller and faster to encode and decode than JSON. Calling a remote service feels like calling a local function.
- Where it shines: service-to-service calls inside a backend, where thousands of internal requests fly around per second and every millisecond counts. The generated code also catches type mistakes at compile time.
- Watch out for: browsers can't speak native gRPC without an extra translation layer, and binary payloads are harder to eyeball when debugging. It's a tool for the engine room, not the storefront.
Side by side
| REST | GraphQL | gRPC | |
|---|---|---|---|
| Format | Usually JSON | JSON, shaped by the query | Binary (protobuf) |
| Transport | HTTP, many URLs + verbs | HTTP, one endpoint | HTTP/2 streams |
| Best for | Public APIs, most apps | Complex UIs, many client types | Internal microservices |
| Watch out for | Over/under-fetching | Server complexity, caching | Not browser-friendly |
A simple rule of thumb
Start with REST. It's the easiest to build, learn, debug, and share, and for most projects it's all you'll ever need. Reach for GraphQL when many different clients keep asking for different slices of your data and you're drowning in custom endpoints. Reach for gRPC when services inside your own backend talk to each other constantly and performance genuinely matters. Plenty of successful systems use all three at once: gRPC between internal services, with REST or GraphQL facing the outside.
Tip: Choosing an API style is rarely a forever decision. A well-organized codebase can add a GraphQL layer or an internal gRPC service later. Pick the simplest thing that works today.
You now have the map that many developers only piece together after years on the job — three styles, three sweet spots, one default. If REST is still a little fuzzy, the friendliest foundation on this site is REST APIs explained with a pizza shop — start there and the comparisons above will click into place.