Last modified: January 24, 2026
This article is written in: 🇺🇸
GraphQL is a query language for APIs that allows clients to request exactly the data they need in a single request. It provides a type system to describe data and offers a more efficient, flexible, and powerful alternative to traditional REST-based architectures. These notes explore the fundamentals of GraphQL, including its anatomy, how it processes queries, common best practices, and example commands illustrating how to interact with a GraphQL server. ASCII diagrams and code blocks provide additional clarity.
GraphQL is a specification and set of tools that enable clients to define the structure of the data required and receive precisely that data from a server. It was initially developed by Facebook to improve the efficiency and flexibility of data fetching in mobile apps, but it has since been widely adopted in various contexts.
The diagram below offers a conceptual view of how a GraphQL client communicates with a GraphQL server, which in turn interacts with one or more data sources (databases, microservices, etc.):
+------------------------+ +------------------------+
| | | |
| GraphQL Client | | GraphQL Server |
| (Web, Mobile, etc.) | | with Schema & Resolvers|
+------------------------+ +-----------+------------+
| 1. Sends Query or Mutation |
|-------------------------------------------->|
| 2. Receives Query |
| Parses & Validates |
| Resolves Fields |
| Fetches Data |
| from Data Sources |
| 3. Gathers Results |
|<--------------------------------------------|
| 4. Receives Response (Precisely the data needed)
|
+------------------------+
| |
| Renders or Processes |
| the Returned Data |
| |
+------------------------+
The client sends a query or mutation describing the shape of the data it wants, the server resolves that request by retrieving information from data sources, and it sends back exactly what was requested.
GraphQL centers around three key concepts: the schema, the query language itself, and resolvers. A schema defines the data types and relationships, the query language allows clients to specify what data they need, and resolvers act as functions that map these requests to actual data.
Schemas in GraphQL are described using a human-readable syntax called the Schema Definition Language. A schema outlines the types, fields, and relationships. For instance:
type Book {
id: ID!
title: String!
author: Author!
}
type Author {
id: ID!
name: String!
books: [Book!]!
}
type Query {
book(id: ID!): Book
books: [Book!]!
author(id: ID!): Author
}
type Mutation {
addBook(title: String!, authorId: ID!): Book!
}
This example schema defines a Book type with an id, title, and an author. It also defines a Query type for retrieving books or authors, and a Mutation type for adding new books.
GraphQL offers three primary operations:
Resolvers are functions that map the fields in a query to actual backend data. A resolver for Query.book might look like this in JavaScript:
const resolvers = {
Query: {
book: (parent, args, context, info) => {
// parent is the result of the previous resolver in the chain
// args contains the arguments passed in the query
// context might hold things like database connections or user info
// info provides query execution details
return context.db.getBookById(args.id);
},
books: (parent, args, context) => {
return context.db.getAllBooks();
}
},
Mutation: {
addBook: (parent, args, context) => {
return context.db.createBook(args.title, args.authorId);
}
},
Book: {
author: (parent, args, context) => {
return context.db.getAuthorById(parent.authorId);
}
}
};
Resolvers can also include logic for caching or transformations. They are where much of the server-side computation and fetching takes place.
GraphQL and REST address similar problems but approach them differently:
A key performance aspect of GraphQL is reducing “over-fetching” and “under-fetching.” Over-fetching happens when a REST endpoint returns unneeded fields, and under-fetching means a client must call multiple endpoints to get all the data it needs.
A simplistic mathematical way to describe potential benefits is to note that REST might require N endpoints to fulfill a complex request, whereas GraphQL can potentially achieve the same result in a single request. If T_rest denotes the total time for multiple requests and T_graph denotes the single GraphQL request time, and if T_graph < T_rest, then GraphQL can offer performance improvements in network-limited scenarios.
There are several considerations for designing and deploying a GraphQL API:
Clients can query a GraphQL server over an HTTP POST request with a JSON body. The table below highlights a few common fields often included in the request:
| Field | Description |
query |
The GraphQL query or mutation string |
variables |
A JSON object holding variable values for the query |
operationName |
Identifies which named operation in the request should execute |
Below are some practical examples of how to interact with a GraphQL API using curl. Each example command is followed by an example response and a brief interpretation.
1) Query Single Book
CODE_BLOCK_PLACEHOLDER - Example output:
CODE_BLOCK_PLACEHOLDER
- Interpretation of the output:
The server returned a JSON object with the requested book data, including the author’s name. The book field matches the query structure.
2) Query List of Books
CODE_BLOCK_PLACEHOLDER - Example output:
CODE_BLOCK_PLACEHOLDER
- Interpretation of the output:
The server responded with an array of books, each containing the id and title. No other fields are included because they were not requested.
3) Mutation: Add a Book
CODE_BLOCK_PLACEHOLDER - Example output:
CODE_BLOCK_PLACEHOLDER
- Interpretation of the output:
A new book was successfully created, returning the book’s id, title, and its associated author object.
Subscriptions enable real-time data. While curl isn’t typically used for real-time operations, the concept is that a client subscribes to an event, like new books being added:
curl -X POST -H "Content-Type: application/json" \
-d '{
"query": "query GetBook($id: ID!) { book(id: $id) { id title author { name } } }",
"variables": {"id": "1"}
}' \
http://example.com/graphql
Whenever a new book is added, the client receives a push notification with the new book data.