GraphQL is a query language for APIs that lets clients request exactly the data they need in a single request. In contrast to REST, where the server decides what data each endpoint returns, GraphQL gives clients full control over the response shape. It was developed by Facebook in 2012 to solve data fetching challenges in their mobile applications.
How It Works
A GraphQL API exposes a single endpoint (typically /graphql) that accepts queries describing the desired data structure. The schema defines types, fields, and relationships using a strongly-typed definition language. Resolvers are server functions that fetch the actual data for each field.
A query like { user(id: 42) { name, email, orders { total } } } returns only the user's name, email, and order totals. Mutations handle writes: mutation { createUser(name: "Alex", email: "[email protected]") { id } }. Subscriptions enable real-time updates over WebSocket connections.
The type system catches errors at development time. Tools like GraphQL Playground provide auto-completion, documentation, and query validation before you write any client code.
Why It Matters
GraphQL solves two persistent REST problems. Over-fetching occurs when an endpoint returns 30 fields but you only need 3. Under-fetching happens when you need data from multiple endpoints, triggering a waterfall of sequential requests. Both problems are acute on mobile where bandwidth and latency are constrained.
For frontend teams, this means developers query exactly what the UI needs without waiting for backend teams to create new endpoints or modify existing ones.
In Practice
GitHub's public API v4 is GraphQL. To display a repository page, a REST approach might require five separate requests (repo details, README, contributors, issues, pull requests). With GraphQL, one query fetches all this data in the exact shape the UI component expects, reducing round trips and eliminating unused data transfer.
Common Mistakes
GraphQL adds complexity: you need a schema, resolvers, and client-side caching (Apollo, urql). Performance pitfalls include the N+1 problem (use DataLoader), deeply nested queries consuming excessive resources (implement query depth limiting), and authorization logic scattered across resolvers. For simple CRUD APIs with few clients, REST is often simpler and sufficient.