Backend
GraphQL
A query language and API specification where the client states exactly which fields it needs.
What it is
GraphQL was created at Facebook (open sourced in 2015) and is now run by the GraphQL Foundation. The server describes a type schema and the client sends a query listing the exact fields.
One endpoint replaces many REST resources. The client gets exactly the data it needs, with no under-fetching (extra requests) and no over-fetching (unneeded fields).
There are three operation kinds: query, mutation and subscription. A typical pitfall is N+1 database queries, solved with DataLoader. Caching is harder than in REST.
Use it when
- Many clients (web, mobile) with different data needs.
- Complex related data and nested queries.
- Frontend teams want to control the response shape themselves.
Avoid it when
- A simple CRUD API with one client: REST is simpler and caches better.
- File uploads and large binary responses.
Key concepts
- Schema
- A typed description of API data and operations.
- Resolver
- A function that returns the value of one field.
- Query / Mutation / Subscription
- Read, write and event stream.
- DataLoader
- Batches and caches loads to avoid N+1.
Example
Cheat sheet
| Command or code | What it does |
|---|---|
query { user(id: 1) { name email } } | Query: select only the fields you need |
query User($id: ID!) { user(id: $id) { name } } | Named query with a variable |
mutation { addPost(title: "Hi") { id } } | Mutation: changes data and returns fields |
subscription { postAdded { id title } } | Subscription to real time events |
type User { id: ID! name: String! posts: [Post!]! } | Type definition in the schema (SDL) |
input NewPost { title: String! body: String } | Input type for mutation arguments |
fragment UserBits on User { id name } | Fragment: a reusable set of fields |
user(id: 1) { name @include(if: $full) } | Directive: conditionally include a field |
{ __schema { types { name } } } | Introspection: the schema describes itself |
Query: { user: (_, { id }, ctx) => ctx.db.user(id) } | Resolver: (parent, args, context) |
How to learn it
- Understand the problem GraphQL solves: a single endpoint where the client picks fields, with no over-fetching and fewer round trips.
- Take the GraphQL essentials course on ShortLesson and write your first query and mutation in GraphiQL.
- Describe a schema (SDL): types, scalars, enums, inputs, interfaces and unions, with
!for non-null. - Build a server on Apollo Server or GraphQL Yoga with resolvers for two related types.
- Hit the N+1 problem, then fix it with DataLoader and confirm it in the database query logs.
- Add authorization in the resolver context, cursor pagination and error handling.
- Connect a client (Apollo Client or urql), its cache and typing through GraphQL Code Generator.
- Read about query complexity limits, persisted queries and federation for larger systems.
Interview questions
1. How does GraphQL differ from REST?
REST has many endpoints with fixed response shapes, GraphQL has one endpoint and the client picks fields. It cuts extra requests but complicates caching and query complexity control.
2. What is the N+1 problem and DataLoader?
It is when a resolver runs a separate database query for each list item. DataLoader collects ids within a tick and makes one batched query.
3. What is introspection?
The ability to ask the server for its own schema. Tools like GraphiQL and type generation rely on it.
Comparisons with this technology
Related technologies
- Node.jsA server-side JavaScript runtime built on the V8 engine with an event-driven, non-blocking I/O model.
- NestJSA progressive TypeScript Node.js framework with modules, decorators and dependency injection.
- FastAPIA modern Python API framework built on type hints, with automatic validation and OpenAPI docs.
- gRPCA remote procedure call framework on HTTP/2 and Protocol Buffers for fast service-to-service communication.
- PrismaAn ORM for Node.js and TypeScript with a schema file, a generated type-safe client and migrations.
Logos belong to their owners and are used for identification only. Icons: Simple Icons (CC0), Devicon (MIT).