GraphQL is not a replacement for REST — it’s an alternative that shines in specific scenarios. Understanding when to use each is more valuable than dogmatically choosing one.
When GraphQL Wins
- Complex, nested data — Fetch articles with authors and comments in one request
- Multiple client types — Mobile apps need different data than web apps
- Rapid iteration — Frontend teams can evolve queries without backend changes
A Simple Schema
type Article {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
createdAt: DateTime!
}
type Query {
article(id: ID!): Article
articles(limit: Int = 25, offset: Int = 0): [Article!]!
}
type Mutation {
createArticle(input: CreateArticleInput!): Article!
}
The N+1 Problem
The biggest pitfall in GraphQL — and how to solve it:
# Without dataloader — N+1 queries!
field :author, Types::UserType, null: false
def author
User.find(object.author_id) # Called for EVERY article
end
# With dataloader — batched!
field :author, Types::UserType, null: false
def author
dataloader.with(Sources::User).load(object.author_id)
end
Rule of thumb: If your clients need predictable, cacheable responses — use REST. If they need flexible, composed responses — consider GraphQL.