Post

GraphQL: Ask for Exactly What You Want

GraphQL lets clients ask for exactly the data they need — no more, no less. Here's what it is, why it exists, and how it compares to REST.

GraphQL: Ask for Exactly What You Want

1. What is GraphQL?

GraphQL is a query language for APIs. It was built by Facebook in 2012 and open-sourced in 2015.

The core idea is simple: instead of the server deciding what data to return, the client describes exactly what it needs. The server then responds with precisely that — nothing more, nothing less.

Three things set GraphQL apart:

  • A single endpoint. Every request goes to one URL (e.g., /graphql). The query itself tells the server what to do.
  • A typed schema. The server publishes a contract — a complete description of every type, field, and relationship available. Clients know what they can ask for before they even send a request.
  • Client-driven queries. The shape of the response mirrors the shape of the query. If I ask for a user’s name and email, that’s all I get back.

2. The Analogy: À La Carte vs. Set Meal

Imagine a restaurant.

REST is the set meal.

I order the “Lunch Special.” Out comes a tray with a burger, fries, coleslaw, a drink, and a dessert. I only wanted the burger and the drink. The rest sits untouched. If I want a salad instead of fries, I have to order a different set meal — or call a different waiter.

GraphQL is ordering à la carte.

I look at the menu (the schema), pick exactly what I want, and hand the waiter my list:

“One burger. One sparkling water. No fries. No dessert.”

The kitchen sends back exactly that. No negotiation, no waste, no extra trips.

The menu is the schema — a public declaration of everything the kitchen can make. My order is the query — a precise description of what I actually want.


3. The Example

Let’s say I’m building a mobile app that shows a user’s profile: just their name and avatar. The backend also stores their address, payment info, post history, and preferences — none of which the profile screen needs.

With REST

I’d hit an endpoint like GET /users/42, and the server would return everything it knows about that user:

1
2
3
4
5
6
7
8
9
10
{
  "id": 42,
  "name": "Boyu",
  "avatar": "https://cdn.example.com/boyu.jpg",
  "email": "boyu@example.com",
  "address": { "street": "...", "city": "...", "zip": "..." },
  "paymentMethod": { "type": "Visa", "last4": "1234" },
  "postCount": 87,
  "preferences": { "theme": "dark", "language": "en" }
}

I asked for a name and an avatar. I got a novel.

With GraphQL

I send this query to POST /graphql:

1
2
3
4
5
6
query {
  user(id: 42) {
    name
    avatar
  }
}

The response is:

1
2
3
4
5
6
7
8
{
  "data": {
    "user": {
      "name": "Boyu",
      "avatar": "https://cdn.example.com/boyu.jpg"
    }
  }
}

That’s it. The shape of my query is the shape of my response. No filtering client-side, no wasted bandwidth.

Here’s where GraphQL really shines. Suppose I also want the user’s last 3 posts, each with a title and a like count. In REST, that’s probably a second request to GET /users/42/posts on top of a GET /users/42. In GraphQL, it’s one query:

1
2
3
4
5
6
7
8
9
10
query {
  user(id: 42) {
    name
    avatar
    recentPosts(limit: 3) {
      title
      likeCount
    }
  }
}

One round trip. One response. Everything the screen needs, nothing it doesn’t.


4. GraphQL vs. REST

Both are tools for building APIs. Neither is universally better. Here’s how they compare across a few dimensions.

 RESTGraphQL
EndpointsMany (/users, /posts, /comments)One (/graphql)
Data shapeFixed by the serverDefined by the client
Over-fetchingCommon — server returns full resourceRare — client asks for only what it needs
Under-fetchingCommon — may need multiple requestsRare — nested queries in one round trip
SchemaInformal (OpenAPI/Swagger is optional)Mandatory and strongly typed
VersioningOften via URL (/v1/users, /v2/users)Schema evolves; old fields are deprecated
CachingEasy — HTTP GET caching works out of the boxHarder — everything is a POST; needs custom solutions
Learning curveLow — REST maps to HTTP verbs intuitivelyHigher — requires understanding schema, queries, mutations

When to reach for GraphQL

  • Multiple clients with different data needs. A mobile app, a web app, and a third-party integration all consume the same API, but each wants a different slice of the data. GraphQL lets each client ask for exactly what it needs without the backend writing custom endpoints for each.
  • Rapidly evolving product. The schema can grow and fields can be deprecated without breaking existing clients.
  • Reducing round trips matters. If a screen needs data from several resources and latency is a concern, collapsing those into one GraphQL query can make a real difference.

When REST is probably fine

  • Simple CRUD. A resource that maps cleanly to create/read/update/delete doesn’t gain much from GraphQL’s flexibility.
  • Public APIs with caching requirements. REST’s native HTTP caching is a significant operational advantage.
  • Small teams or early-stage products. REST is simpler to set up, simpler to reason about, and has a bigger tooling ecosystem. Don’t pay the GraphQL tax before you need to.

5. The Takeaway

GraphQL didn’t replace REST — it solved the problems REST has in complex, multi-client systems.

The key mental shift is this: in REST, the server decides what a response looks like. In GraphQL, the client does. That shift puts more power in the hands of frontend developers and eliminates entire categories of over-fetching and under-fetching problems.

If my API serves one type of client and the data model is stable, REST is probably the right call. If I’m building a platform where different clients need different cuts of the same data, GraphQL is worth the learning curve.

As always — pick the tool that fits the problem, not the one that sounds cooler.

This post is licensed under CC BY 4.0 by the author.