GraphQL Introduction
What GraphQL is, the over-fetching/under-fetching problems it solves, and a first query example.
What GraphQL is
GraphQL is a query language for APIs, along with a runtime for executing those queries against your data. It was created at Facebook in 2012 and open-sourced in 2015. Unlike REST, where the server defines a fixed set of endpoints that each return a fixed shape of data, GraphQL exposes a single endpoint and lets the client describe exactly what data it needs, in exactly the shape it needs it, in the request itself.
POST /graphql
Content-Type: application/json
Every request — whether reading or writing data — goes to that one URL. What changes between requests is the query sent in the body, not the URL.
The problem it solves: over-fetching and under-fetching
Consider a mobile app screen that shows a blog post's title, its author's name, and a count of its comments — nothing else. With a typical REST API, you're often stuck choosing between two bad options.
Over-fetching — the existing endpoint returns far more than you need:
GET /posts/123
{
"id": 123,
"title": "Understanding GraphQL",
"body": "... 4,000 words of article content ...",
"createdAt": "2026-01-14T09:00:00Z",
"updatedAt": "2026-02-01T11:30:00Z",
"tags": ["graphql", "api-design"],
"author": { "id": 7, "name": "Ali Raza", "bio": "...", "avatarUrl": "...", "email": "..." },
"comments": [ { "id": 1, "body": "...", "author": {...} }, "... 40 more ..." ]
}
The screen needed 3 fields; the response shipped the entire article body, every comment in full, and fields the mobile client will never render — wasted bandwidth and parsing time, especially painful on slow mobile connections.
Under-fetching — the opposite problem, where a single endpoint doesn't return enough, forcing the client to make several round-trips to assemble one screen:
GET /posts/123 -> get the post (but author is just an ID: 7)
GET /authors/7 -> get the author's name
GET /posts/123/comments -> get comments, then count them client-side
Three separate network round-trips, each with its own latency, just to render one screen. As an app grows more screens with different data needs, REST APIs tend to accumulate either bloated general-purpose endpoints (over-fetching) or a sprawl of narrow, screen-specific endpoints (under-fetching, solved the hard way).
Ask for exactly what you need
GraphQL solves both problems the same way: the client sends a query describing the exact shape of data it wants, and the server returns a response in exactly that shape — no more, no less.
query {
post(id: 123) {
title
author {
name
}
commentCount
}
}
{
"data": {
"post": {
"title": "Understanding GraphQL",
"author": {
"name": "Ali Raza"
},
"commentCount": 42
}
}
}
One request. One round-trip. The response's shape mirrors the query's shape exactly — nothing extra, nothing missing. A different screen that needs more fields (the full body, all comments, tags) just asks for more in its own query, against the exact same endpoint and the exact same underlying data — no new endpoint needs to be designed or deployed on the server for it.
REST vs GraphQL, side by side
| REST | GraphQL | |
|---|---|---|
| Endpoints | Many, one per resource/action | One |
| Response shape | Fixed by the server per endpoint | Determined by the client's query |
| Over-fetching | Common | Avoided by design |
| Under-fetching (multiple round-trips) | Common for nested/related data | Avoided — nested data is one query |
| Caching | Simple (HTTP caching works out of the box, keyed by URL) | Requires more deliberate client-side cache design |
| Learning curve | Lower, widely understood | Steeper — a schema and query language to learn |
Neither replaces the other universally — REST's simplicity and out-of-the-box HTTP caching still make it the right default for many APIs, while GraphQL earns its complexity when clients have diverse, evolving data needs (a public API serving both a mobile app and a web app with different screens, for instance).
Common mistakes
- Assuming GraphQL is "faster" than REST inherently — it solves a data-shape problem (fetching exactly what's needed in one round-trip), not a raw network speed problem. A poorly designed GraphQL schema can still be slow (see the N+1 problem, covered later in this track).
- Treating every field in a GraphQL query as free — the server still has to resolve each field, often with real work (a database query) behind it.
- Assuming GraphQL replaces REST everywhere — plenty of simple APIs are better served by REST's simplicity and built-in HTTP caching.
Interview questions
Q: What core problems does GraphQL solve that plain REST APIs commonly run into? Over-fetching (a REST endpoint returning more fields than a particular client needs) and under-fetching (a client needing multiple round-trips to assemble related data from separate endpoints). GraphQL lets the client specify exactly the fields and nested relationships it wants in a single request, and the server returns a response matching that exact shape.
Q: How many endpoints does a typical GraphQL API expose, and why?
Typically just one (commonly /graphql). Instead of the URL determining what data comes back, as in REST, the query sent in the request body determines it — so different clients with very different data needs can all talk to the same single endpoint.