Skip to content
HLD Learn/APIs, Done Right
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

GraphQL & gRPC: When to Reach Beyond REST

6 min read

You'll learn to

  • -Explain over-fetching and under-fetching with a worked count of calls and fields
  • -Explain how GraphQL fixes both, and its costs: the N+1 problem, harder caching, and query cost
  • -Explain what gRPC and Protocol Buffers offer and why they suit internal service calls
  • -Choose between REST, GraphQL and gRPC for a given scenario

REST is the default, but it has two awkward habits that show up as an API and its clients grow. Two other styles, GraphQL and gRPC, exist to fix different problems, and an interviewer will often ask when you would reach for them. This chapter explains the problem each one solves and what it costs, so you can answer with a reason and not a preference.

An Analogy: The Set Menu, À la Carte, and the Kitchen Hotline

A REST API is like a restaurant with fixed set menus. Each menu comes as it is: if you wanted only the fries, you still get the whole combo (wasted food), and if you wanted a burger, a salad and a drink from three different counters, you have to queue at all three. GraphQL is à la carte: you give the waiter one order listing exactly what you want from every counter, and one tray comes back. gRPC is the hotline between two kitchens in the same building: a private line using a shorthand both sides agreed in advance, very fast, but not something a passer-by can use.

  • -The set menu that comes whole is a fixed REST response, and the unwanted food is over-fetching.
  • -Queuing at three counters is under-fetching: several round trips for one screen.
  • -The single à la carte order is a GraphQL query.
  • -The private shorthand hotline is gRPC with Protocol Buffers.

The Problem: Over-Fetching and Under-Fetching

A REST endpoint returns a fixed shape. If it returns 30 fields and a mobile client needs 3, that is over-fetching: wasted bandwidth, which matters on a slow phone connection. If drawing one screen needs data from several endpoints, that is under-fetching: wasted round trips. Take a profile screen that shows a user's name, avatar and the titles of their last three orders. With REST you might call GET /users/42 (30 fields, you need 2), then GET /users/42/orders (20 fields per order, you need 1), and perhaps one more call per order for its details: three to five round trips, most of the data thrown away.

GraphQL: Ask for Exactly What You Need

With GraphQL the client describes exactly which fields it wants, across as many related resources as it likes, in a single query to a single endpoint:

One request, one response, containing exactly the fields the screen needs and nothing else
query {
  user(id: 42) {
    name
    avatarUrl
    orders(last: 3) {
      title
    }
  }
}

That solves over-fetching and under-fetching together, and lets frontend teams change what they ask for without waiting for a new endpoint. But the cost moves to the server, in three places.

  • -The N+1 problem. Say a query fetches 20 posts and then, for each post, fetches its author with a separate database query. That is 1 + 20 = 21 queries where batching could do it in 2. The standard fix is a batching layer (often called a data loader).
  • -Harder caching. REST gets cheap caching for free because each URL names one thing. GraphQL usually sends every query to the same URL, so caching has to be done in other ways.
  • -Query cost. A client can ask for deeply nested data that is very expensive to produce, so servers set limits on depth and cost.

gRPC: Fast, Strict Calls Between Services

gRPC is Google's remote procedure call framework. Instead of JSON text, it sends Protocol Buffers, a compact binary format, over HTTP/2, which can carry many calls on one connection and supports streaming in either direction. Typically the same data is noticeably smaller and quicker to encode than as JSON, and in a chain of services where every call adds up, that matters. The interface is written first, in a contract file, and client and server code is generated from it:

The contract: a service with one call, and the shape of its request. Both sides get type-checked code generated from this file
service OrderService {
  rpc GetOrder (GetOrderRequest) returns (Order);
}

message GetOrderRequest {
  int64 id = 1;
}

The strictness is both the strength and the limit. Because both sides share a typed contract, mistakes are caught at build time. But browsers cannot call gRPC directly without a translation layer, so it is a poor fit for public, browser-facing APIs, and a good one for traffic between your own services.

Choosing

  • -A public API used by many unknown clients: REST, for its simplicity, caching and tooling.
  • -Several different clients (mobile, web) that need different slices of connected data: GraphQL.
  • -Internal service-to-service calls where latency and strict contracts matter: gRPC.

Plenty of companies use all three: REST for partners, GraphQL for their own apps, and gRPC inside. The deeper treatment lives in ScaleDojo's API Design lab track.

ScaleDojo's API Design lab track goes much deeper on REST, GraphQL, and API architecture generally; this chapter is the on-ramp, not the whole story.

In one line: REST returns fixed shapes, which causes over-fetching and under-fetching. GraphQL lets the client ask for exactly what it needs, at the price of N+1 queries, harder caching and cost limits. gRPC is a fast, strictly typed binary protocol best kept between your own services.

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

Ready to Build This?

Level 12: Search Autocomplete exercises a rich, well-versioned API surface.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!