Most HTTP APIs expose fixed resource shapes: each URL returns a predetermined JSON document, and clients either accept the extra fields or stitch several calls together. GraphQL inverts part of that contract. The client sends a document written in the GraphQL language; the server validates it against a schema, runs resolvers for each requested field, and returns JSON whose keys mirror the query. One round trip can fetch a graph of related objects, but the team must invest in schema design, performance limits, and client tooling.
How GraphQL started
Facebook began GraphQL in 2012 to simplify mobile clients that needed different slices of the same backend data. The specification and reference implementations were open sourced in 2015. The GraphQL Foundation (under the Linux Foundation) now stewards the spec; implementations exist in TypeScript, Java, Go, Rust, and many other languages. The spec evolves through RFC-style proposals; breaking changes to the language itself are rare, while your schema changes are where day-to-day compatibility work happens.
What clients send and what servers return
Clients usually POST a JSON body to a single path (often /graphql):
{ "query": "query { user(id: \"1\") { name email } }", "variables": {}, "operationName": "GetUser"}The response is also JSON:
{ "data": { "user": { "name": "Ada Lovelace", "email": "ada@example.com" } }, "errors": []}| Key | Role |
|---|---|
data |
Successful field values, shaped like the query |
errors |
Spec violations, resolver failures, or partial failures |
extensions |
Optional server metadata (tracing, rate limits, codes) |
GraphQL allows partial success: if a non-null field throws, that branch may become null while sibling fields still return data, and errors explains what failed. That behavior matters when designing nullability on the schema.
Request lifecycle
flowchart LR client[Client document] parse[Parse] validate[Validate against schema] execute[Execute resolvers] json[JSON response] client --> parse --> validate --> execute --> json
- Parse turns the text into an abstract syntax tree.
- Validate checks that every field, argument, and fragment exists on the schema and that types line up.
- Execute walks the selection set. For each field, the runtime calls the matching resolver (or a default that reads a property on the parent object).
- Execution stops at scalar values (strings, numbers, booleans, IDs, or custom scalars). Object fields trigger deeper resolver calls until scalars are reached.
The schema is the contract between teams: it lists types, fields, and arguments but does not dictate whether data comes from SQL, REST, or an in-memory list.
GraphQL compared with REST and RPC
REST versus RPC compares two styles of HTTP APIs. GraphQL is often layered on top of REST or RPC backends as a facade: resolvers translate GraphQL fields into existing services.
| Concern | Typical REST | GraphQL |
|---|---|---|
| Shape of response | Defined by the server per URL | Defined by the client per request |
| Round trips | One resource per call unless custom batch endpoints | One request for a tree of fields |
| Caching | HTTP cache keys on URLs | POST bodies need client or CDN strategies |
| Versioning | Paths or headers (/v2/...) |
Continuous schema evolution with deprecation |
| Discovery | OpenAPI documents | Schema introspection (often restricted in production) |
GraphQL does not automatically solve over-fetching on the server: resolvers may still load wide database rows. It reduces wire over-fetching when clients omit fields they do not need.
When GraphQL fits and when it does not
GraphQL tends to pay off when many clients (web, mobile, partners) need different views of the same domain, when product teams want to iterate on UI without waiting for new REST endpoints, or when you are aggregating several backends behind one typed API.
It is a harder sell when the API is small and stable, when HTTP caching at the edge is the main performance story, when uploads and downloads are mostly binary blobs, or when the team lacks capacity for query cost limits, authorization per field, and schema governance. File uploads and long-running jobs are usually handled with REST, gRPC, or dedicated endpoints alongside GraphQL.
Tools for learning an API
During development, GraphiQL or Apollo Sandbox provide an editor, schema docs, and variable panels against your endpoint. GraphQL Voyager visualizes types as a graph. These tools rely on introspection; production APIs often disable or gate introspection for unauthenticated callers—a topic covered later in the security chapters.
Next: Schemas and SDL.
Check your understanding
Question 1 of 6
0 of 6 checked