What Is GraphQL? β Definition and How It Works
Learn what GraphQL is, how a typed schema and single endpoint work, what queries and mutations look like, and the trade-offs against REST.
GraphQL is a query language for APIs in which the client states exactly which fields it wants and receives precisely those. One endpoint serves every query, and a typed schema defines what is available.
1. What Is GraphQL?
It moves response shaping from the server to the client.
- Key idea: the client declares the shape of the data it needs.
- Mechanism: a POST to a single endpoint carrying a query document, validated against a schema.
- Goal: eliminate over-fetching and the round trips that come from fixed endpoints.
Example Query and Response
query {
product(id: "A-4192") {
name
price
reviews(first: 2) { rating body }
}
}
{ "data": { "product": { "name": "...", "price": 49.9,
"reviews": [ { "rating": 5, "body": "..." }, { "rating": 4, "body": "..." } ] } } }
The response mirrors the query's shape exactly.
2. The Schema Is the Contract
Every field, type, and argument is declared in a typed schema. Clients can introspect it, which is why GraphQL tooling offers autocompletion and validation without external documentation.
type Product {
id: ID!
name: String!
price: Float
reviews(first: Int): [Review!]!
}
An exclamation mark marks a non-null field. The schema is checked at query time, so malformed requests fail before execution.
3. Queries, Mutations, Subscriptions
- Query β read data. No side effects.
- Mutation β write data. Executed serially so ordering is defined.
- Subscription β a long-lived stream of updates, usually over websockets.
4. Compared With REST
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoints | Many, one per resource | One |
| Response shape | Fixed by the server | Chosen by the client |
| Over-fetching | Common | Avoided by design |
| Round trips for related data | Often several | Usually one |
| HTTP caching | Straightforward on GET | Harder β most requests are POSTs to one URL |
| Error signalling | Status codes | Usually 200 with an errors array |
That last row surprises people: a GraphQL response can be 200 OK and still contain nothing but errors, so clients must inspect the body rather than the status.
5. The Costs
- Server complexity. Arbitrary client queries can be expensive; depth limits, complexity scoring, and persisted queries exist to bound them.
- The N+1 problem. A nested field can trigger one database call per parent unless batching is applied.
- Caching. The HTTP layer no longer helps much, so caching moves into the application.
- Authorisation granularity. Permission has to be enforced per field, not per endpoint.
6. Where It Fits
GraphQL suits clients with varied data needs β several front ends over one backend, mobile apps minimising payload size, or dashboards composing many related entities.
It is less compelling for a simple resource API with one consumer, where REST is easier to cache and operate.
7. Common Misconceptions
- "GraphQL replaces the database." It is an API layer; resolvers still call whatever storage exists.
- "It is always fewer requests." One request, but potentially far more server work behind it.
- "Status 200 means success." Check the
errorsarray. - "Introspection is always on." Many production deployments disable it, and query documents are often allow-listed.
8. Summary
GraphQL gives clients a typed schema and a single endpoint where they specify the exact fields they want, removing over-fetching and multi-round-trip assembly of related data.
The cost lands on the server: query cost control, batching to avoid N+1 queries, application-level caching, and field-level authorisation. Where several clients have divergent needs, that trade is usually worth making.