Skip to main content
REST vs GraphQL vs gRPClesson 1 of 4 · 2 min read

REST and Its Limits

Resources with addresses

REST treats your API as a set of things with addresses, and uses the HTTP verbs to say what you are doing to them. GET reads a user, POST creates an order, DELETE removes one.

That sounds like a small convention, and it hands you the entire HTTP ecosystem for free. Your GET requests can be cached by browsers, by CDNs, and by any proxy in between, because the verb itself promises nothing changes. Status codes carry meanings every client already knows. Anything with an HTTP library can call you, with no SDK to install.

Keep it stateless, which is the other pillar. Each request carries everything your server needs, so any machine behind the balancer can answer it. That is why REST spreads across machines without ceremony, and why it stays the default for public APIs that strangers consume.

Where it strains

Watch the strain arrive in two shapes. The first is fetching too much: your user endpoint returns forty fields when the phone screen wants a name and a picture. On a weak connection that wasted payload is real latency and real battery.

The second is worse, which is fetching too little. A screen showing a user, their last five orders, and the items in each needs three trips one after another, because each answer tells you what to ask for next. At 80 milliseconds a trip on mobile, that screen pays 240 milliseconds before it draws anything.

Patch it and watch the patches accumulate. You add a parameter listing the fields you want, or a bespoke endpoint built for one screen. Both work until you have thirty of them and nobody remembers which frontend owns which.

Pile of one-off endpoints, because it is the exact pain the next lesson was built to remove.

the shape of it
Mobile appGET /ordersGET /restaurantsone per orderGET /couriersone per couriertrip 1trips 2-11trips 12-14
step 1 of 3
Under-fetching in REST: each response reveals the next round trip, and mobile latency multiplies.

Worked example

Marta's team at a food delivery startup ships an order history screen in their iOS app. It calls GET /orders, then GET /restaurants/:id for each of the 10 orders shown, then GET /couriers/:id for the three active ones: 14 requests to paint one screen. On LTE their p50 screen load is 1.9 seconds, and the analytics funnel shows 12 percent of users leaving before it finishes. The backend team adds a purpose-built GET /orders/history-screen endpoint that joins everything server-side, cutting the load to one request and 420 ms. It works, but six months later there are 23 such screen-shaped endpoints, and renaming a field means grepping three frontend repos. That maintenance tax, not the latency, is what finally puts GraphQL on their roadmap.