<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> REST vs. GraphQL

REST vs. GraphQL

As apps grow, especially when multiple clients (web, mobile, third-party) hit the same API, two friction points emerge with plain REST: over-fetching (getting more fields than you need) and under-fetching (needing multiple round trips to assemble a view). GraphQL was designed specifically to fix both: a single endpoint where the client describes exactly the data it wants, and the response mirrors the shape of the query.

query {
  books {
    title          # only this
    author {
      name         # and this
    }
  }
}

Notice what you just read in the previous lessons, though: JSON:API gives REST the same two powers. Sparse fieldsets are field selection; include is nested fetching. The real differences lie elsewhere:

REST + JSON:API Client GET /books GET /authors GET /reviews many URLs · one per resource GraphQL Client POST /graphql one endpoint one query · exact shape
REST spreads a view across several resource URLs; GraphQL exposes one endpoint where the query body decides exactly which records and fields come back.
REST + JSON:API GraphQL
Where requests go A separate URL per resource: /books, /authors, /books/42. One endpoint (e.g. /graphql); the query in the request body decides what you get back.
Picking fields Opt in per type with a query param (fields[books]=title). Leave it off and you get every field. Built in: every query spells out the exact fields it wants, every time.
Pulling in related data Ask for it explicitly with include=author; it comes back alongside the main resource. Nest it right in the query (author { name }) and it's fetched in the same round trip.
HTTP caching Reads are GETs with stable URLs, so browsers, CDNs, and proxies cache them for free. Everything is a POST to one URL, so HTTP caching doesn't apply on its own. You need persisted queries or a client-side cache.
How the API is defined By convention and written docs: nothing enforces the shape. A typed, introspectable schema; tools can autocomplete and validate a query before it's even sent.
Cost on the server Each endpoint runs a known, fixed query, so the load is predictable. Clients compose arbitrary queries, so a deeply nested one can fire off N+1 database calls unless you batch them (e.g. with DataLoader).

The schema doubles as a security boundary. If a field isn't in the GraphQL schema, no client can ever ask for it. The rule lives in one place. REST has no single gate like this: whether a field is exposed is decided endpoint by endpoint, so it's easy to leak one by forgetting to strip it.

So which should you reach for? REST with JSON:API conventions is hard to beat for public, cacheable, CRUD-style APIs, the kind where each client wants roughly the same data. GraphQL earns its extra complexity when lots of clients each need a different slice of the same rich data, and you'd rather hand them one flexible contract than build a new endpoint for every view.

Check your understanding

Question 1 of 2

One query per author in the DB

Your GraphQL API answers one HTTP request per view, but the database logs show one query per book's author. What's happening?