π· GraphQL vs. REST Architecture
REST built the modern web, but it makes the client fetch data on the server's terms. GraphQL flips that: the client asks for exactly the shape it needs, in one request, against one strongly-typed endpoint. This lesson gives you a clear mental model of both, the real trade-offs, and how to decide which one fits a given problem.
π― Learning Objectives
By the end of this lesson, you will be able to:
- Explain what GraphQL is and the problems it was designed to solve
- Diagnose over-fetching, under-fetching, and the N+1 request patterns in REST
- Describe GraphQL's core principles β a single typed endpoint, declarative fetching, and introspection
- Compare REST and GraphQL and choose the right one for a given scenario
- Identify the major tools in the GraphQL ecosystem
Estimated Time: 30β40 minutes β’ Difficulty: Intermediate
Hands-on: Rewrite a multi-request REST feature as a single GraphQL query.
In This Lesson
What Is GraphQL?
GraphQL is a query language for APIs and a runtime that executes those queries against your data. It was created at Facebook in 2012 to power their mobile apps, open-sourced in 2015, and is now governed by the vendor-neutral GraphQL Foundation. Crucially, it is a specification, not a specific piece of software β you can implement or consume it in any language.
The one idea to hold onto: with GraphQL the client describes the data it wants, and the server returns exactly that β no more, no less β as a JSON response shaped like the request.
π‘ A shopping analogy. A REST API is like a row of specialty shops: you go to the bakery for bread, the butcher for meat, and the greengrocer for vegetables β several trips to several counters. GraphQL is like handing a single personal shopper your whole list; they make one trip and bring back precisely what you asked for.
π Key Terms
Endpoint: a URL a client sends requests to. REST APIs expose many; GraphQL usually exposes exactly one (commonly /graphql).
Over-fetching: the server returns fields the client never uses.
Under-fetching: one response isn't enough, so the client must make additional requests to complete the picture.
Where REST Strains
REST (Representational State Transfer) has been the default API style for two decades, and for good reason: it maps cleanly onto HTTP, benefits from HTTP caching, and is simple to reason about. But as UIs grew more data-hungry and clients diversified (web, iOS, Android, smart TVs), a few recurring pain points emerged.
Over-fetching and under-fetching
Say a mobile list only needs each user's name and avatar. A REST GET /api/users typically returns the entire user record β email, bio, timestamps, settings β wasting bandwidth on a metered connection. That's over-fetching. Conversely, to render one profile screen you might need the user, their recent posts, and their followers β three endpoints, three round trips. That's under-fetching.
The N+1 request problem
Under-fetching compounds badly in lists. Suppose you want to show 20 blog posts, each with its comments:
GET /api/posts # 1 request β returns 20 posts
GET /api/posts/1/comments # + 1 request
GET /api/posts/2/comments # + 1 request
... # ...one per post
GET /api/posts/20/comments
That's 1 + 20 = 21 requests just to paint one screen β the classic N+1 pattern. Each request carries its own latency, headers, and connection overhead. GraphQL lets the client express the whole nested need in a single request, and it becomes the server's job to fetch it efficiently.
β οΈ REST is not "wrong"
These are pressures, not defects. For simple resource CRUD, file uploads, or public APIs that lean on HTTP caching, REST is often the better choice. GraphQL trades some of REST's simplicity and free caching for flexibility β a trade that only pays off when your data needs are genuinely varied and nested.
GraphQL's Core Principles
GraphQL addresses those pressures through a handful of deliberate design choices:
- Declarative data fetching β the client states the exact fields it wants; the response mirrors that shape.
- A single endpoint β every operation is a
POSTto one URL (typically/graphql), so there are no endpoint maps to memorize. - A strong type system β a schema declares every type and field, giving you validation, editor autocomplete, and a living contract.
- Introspection β the API can be queried for its own schema, which powers tooling like GraphiQL and Apollo Sandbox.
- Hierarchical & composable β queries nest to match your UI's component tree, and fragments let you reuse selections.
A Side-by-Side Comparison
Consider building a social profile screen that shows a user, their posts, and their friends.
The REST approach
GET /api/users/123
GET /api/users/123/posts
GET /api/users/123/friends
Three round trips, each returning a full record, and the client stitches the pieces together.
The GraphQL approach
query ProfilePage($id: ID!) {
user(id: $id) {
name
email
posts {
title
createdAt
}
friends {
name
avatarUrl
}
}
}
One request names exactly the fields the screen renders. The response comes back in the same shape:
Response
{
"data": {
"user": {
"name": "Ada Lovelace",
"email": "ada@example.com",
"posts": [
{ "title": "On Analytical Engines", "createdAt": "2026-05-01" }
],
"friends": [
{ "name": "Charles Babbage", "avatarUrl": "/img/cb.png" }
]
}
}
}
Choosing Between Them
Neither wins outright. Match the tool to the shape of the problem.
| Reach for GraphQL when⦠| Reach for REST when⦠|
|---|---|
| Screens need deeply nested, related data | You do simple CRUD on single resources |
| Many clients each need different field sets | You lean heavily on HTTP/CDN caching |
| You aggregate data from several back ends | You handle binary uploads or file streaming |
| Bandwidth is precious (mobile) | The API is small with a handful of endpoints |
| Requirements change often and the UI evolves fast | You want to reuse mature REST infrastructure |
π‘ Hybrid is common and healthy
Plenty of teams run both: GraphQL for the product-facing app where data needs are varied, and REST (or gRPC) for internal service-to-service calls, webhooks, and file endpoints. Choosing GraphQL is not an all-or-nothing migration.
The GraphQL story shows up at scale, too. GitHub's REST v3 API exposed dozens of endpoints for repositories alone; its GraphQL API consolidated access behind one schema and let clients fetch precisely the fields a page renders. Shopify, Netflix, and others report similar gains in front-end simplicity β though all of them also pay GraphQL's costs in caching complexity and query-cost management.
The GraphQL Ecosystem
Because GraphQL is a spec, a healthy ecosystem of implementations exists across languages and both sides of the wire:
π Note on tooling names
You may still see references to GraphQL Playground; it is now deprecated in favor of GraphiQL and Apollo Sandbox. Likewise, the standalone apollo-server package has been superseded by @apollo/server (v4+). We use the current packages throughout this module.
Hands-on Exercise
ποΈ Collapse a REST feature into one GraphQL query
Objective: Turn a multi-request REST feature into a single declarative query and reflect on the trade-offs.
Instructions:
- Pick a real feature β an e-commerce product page is a good one.
- List the REST endpoints it would call today (product, reviews, related items, stock).
- Write one GraphQL query that returns everything the page renders, and nothing it doesn't.
- In two sentences, note one advantage and one drawback of the GraphQL version for this feature.
π‘ Hint
Think in terms of the page's component tree: the product card, the reviews list (each with its author), a "related products" strip, and an availability badge. Each nested UI piece maps to a nested selection set.
β Sample solution
REST today:
GET /api/products/123
GET /api/products/123/reviews
GET /api/products/123/related
GET /api/inventory/product/123
One GraphQL query:
query ProductPage($id: ID!) {
product(id: $id) {
name
price
description
images { url alt }
reviews {
rating
comment
user { name }
}
relatedProducts {
id
name
price
thumbnail
}
inventory {
inStock
availableSizes
shippingEstimate
}
}
}
Advantage: one round trip returns exactly the fields the page needs, ideal on mobile. Drawback: you lose free per-endpoint HTTP caching, so you must add query-level caching and guard against expensive nested queries.
Quiz
π― Check Your Understanding
Question 1: A mobile list needs only each user's name, but GET /api/users returns the full record every time. What is this called?
Question 2: Which statement about GraphQL endpoints is accurate?
Question 3: For which scenario is plain REST usually the better fit?
Summary
π Key Takeaways
- GraphQL is a spec: the client declares the exact fields it wants and the response mirrors that shape.
- It targets REST's over-fetching, under-fetching, and N+1 patterns with one typed endpoint.
- Its pillars are declarative fetching, a single endpoint, a strong type system, and introspection.
- REST still wins for simple CRUD, file transfers, and cache-heavy public APIs β hybrid setups are normal.
- The ecosystem is mature: Apollo Client/Server, urql, Relay, GraphQL Yoga, GraphiQL, and Code Generator.
π Further Reading
- GraphQL.org β Official learning guide
- How to GraphQL β Full-stack tutorial
- Apollo GraphQL documentation
- GitHub β Why we built a GraphQL API
π What's Next?
Now that you know why GraphQL exists, the next lesson β Schema Definition and Types β dives into the schema itself: the strongly-typed contract that makes all of this possible.
π Nice work!
You can now explain GraphQL, spot REST's pain points, and pick the right tool for a job. Time to design the schema.