GraphQL Introduction
Alternative to REST - query exactly what you need with GraphQL.
3 min read
What is GraphQL?#
GraphQL is a query language for APIs. Instead of fixed endpoints, clients request exactly what they need:
graphql
# REST: Multiple requests, over-fetching
GET /users/123
GET /users/123/posts
GET /users/123/followers
# GraphQL: One request, exact data
query {
user(id: "123") {
name
email
posts {
title
}
followers {
name
}
}
}
REST vs GraphQL#
| Aspect | REST | GraphQL |
|---|---|---|
| Endpoints | Multiple (/users, /posts) | Single (/graphql) |
| Data fetching | Fixed responses | Client specifies fields |
| Over-fetching | Common | Never |
| Under-fetching | Requires multiple calls | Single query |
| Versioning | URL or header versions | Schema evolution |
| Caching | HTTP caching easy | More complex |
| Learning curve | Lower | Higher |
When to Use GraphQL#
Good for:#
- Mobile apps - Minimize data transfer
- Complex UIs - Many related entities
- Multiple clients - Different data needs
- Rapid iteration - Schema evolves easily
Stick with REST for:#
- Simple CRUD - GraphQL is overkill
- File uploads - REST handles better
- Caching critical - HTTP caching simpler
- Team unfamiliar - Learning curve
Core Concepts#
Schema Definition#
graphql
# Define types
type User {
id: ID!
email: String!
name: String!
posts: [Post!]!
createdAt: String!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
text: String!
author: User!
}
# Queries (read)
type Query {
user(id: ID!): User
users(page: Int, limit: Int): [User!]!
post(id: ID!): Post
posts: [Post!]!
}
# Mutations (write)
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
createPost(input: CreatePostInput!): Post!
}
# Input types
input CreateUserInput {
email: String!
password: String!
name: String!
}
input UpdateUserInput {
name: String
email: String
}
input CreatePostInput {
title: String!
content: String!
}
Queries#
graphql
# Simple query
query {
user(id: "123") {
name
email
}
}
# With variables
query GetUser($id: ID!) {
user(id: $id) {
name
email
posts {
title
}
}
}
# Multiple queries
query Dashboard {
currentUser {
name
notifications {
message
}
}
recentPosts(limit: 5) {
title
author {
name
}
}
}
Mutations#
graphql
# Create
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
email
name
}
}
# Update
mutation UpdateUser($id: ID!, $input: UpdateUserInput!) {
updateUser(id: $id, input: $input) {
id
name
email
}
}
# Variables
{
"input": {
"email": "user@example.com",
"password": "password123",
"name": "John Doe"
}
}
Subscriptions (Real-time)#
graphql
subscription OnNewComment($postId: ID!) {
commentAdded(postId: $postId) {
id
text
author {
name
}
}
}
Popular Libraries#
| Library | Best For | Features |
|---|---|---|
| Apollo Server | Most projects | Full-featured, great DX |
| GraphQL Yoga | Lightweight | Simple, plugin-based |
| Mercurius | Fastify | Fast, Fastify integration |
| Pothos | TypeScript | Type-safe schema building |
Quick Comparison#
javascript
// REST
app.get('/users/:id', async (req, res) => {
const user = await User.findById(req.params.id);
res.json({ data: user }); // Always returns all fields
});
// GraphQL
const resolvers = {
Query: {
user: (_, { id }) => User.findById(id),
// Client chooses which fields to receive
},
};
Key Takeaways#
- GraphQL = flexible queries - Client requests exact data
- Single endpoint - All operations through
/graphql - Strongly typed - Schema defines everything
- Good for complex apps - Multiple related entities
- Higher complexity - Not always needed
Continue Learning
Ready to level up your skills?
Explore more guides and tutorials to deepen your understanding and become a better developer.