Understanding GraphQL: What It Is and When to Use It


GraphQL is a query language for your API and a runtime for executing those queries by using a type system you define for your data. Unlike REST, which uses fixed endpoints and returns fixed data structures, GraphQL allows clients to request exactly the data they need—and nothing more.
At its core, GraphQL is about flexibility and precision. Clients send queries to the server describing their data requirements. The server processes these queries based on a defined schema, which outlines available queries, mutations, types, and relationships.
What Problems Does GraphQL Solve?
✅ Over Fetching and Under Fetching
With REST, endpoints often return too much or too little data, requiring additional requests or client-side filtering. GraphQL eliminates this by allowing clients to fetch only the data they need.
✅ Multiple Network Requests
A typical REST API may require several requests to fetch related resources. GraphQL consolidates these into a single request, making APIs more efficient.
✅ Tight Coupling Between Client and Server
In REST, any frontend change may require the backend to expose a new endpoint or modify an existing one. GraphQL decouples this by exposing a schema that the frontend can query independently.
✅ Type Safety Across Client and Server
GraphQL schemas are strongly typed. Clients can automatically infer types from the schema, improving developer experience and reducing runtime errors.
GraphQL vs. REST
⚙️ Performance
REST: Faster for small, flat data. Ideal for simple APIs with limited nesting.
GraphQL: Excels in complex data scenarios with deep nesting and flexible requirements. No need for multiple round trips—just one request can include all the necessary data.
GraphQL uses field resolvers to fetch only the requested fields, which helps in deferring expensive operations unless required.
💻 Developer Experience
GraphQL offers introspection, type safety, and interactive tools like Apollo Playground or GraphiQL.
REST requires strict API contracts and documentation, and often multiple endpoints for different data shapes.
GraphQL's self-documenting schema makes frontend development faster and more intuitive. Instead of relying on written docs, developers can query available operations directly.
⚠️ One trade-off: GraphQL queries can become verbose for large nested data trees, making code harder to maintain if not modularized properly.
📌 Versioning
GraphQL: No need for v1, v2, etc. You deprecate fields instead of endpoints. Backward-compatible changes can evolve naturally.
REST: Requires maintaining multiple versions of the same endpoint, which can get messy over time.
🚨 Error Handling
REST uses HTTP status codes to indicate success or failure.
GraphQL always returns
200 OK
, even when an error occurs. Errors are returned inside theerrors
field of the response.
⚠️ While this aligns with GraphQL's design, it can be counterintuitive. Proper tooling is necessary to distinguish between successful data and partial failures.
🧠 Caching
REST: Integrates well with HTTP caching (e.g.,
ETag
,Cache-Control
headers), CDNs, and browsers.GraphQL: Requires client-side libraries (like Apollo Client) or server-side logic for caching. Not as straightforward.
🔁 Real-Time Support
GraphQL supports real-time updates via subscriptions using WebSocket connections.
REST doesn’t support real-time natively—requires workarounds like polling or custom socket implementations.
GraphQL subscriptions let clients open a WebSocket and receive live updates when data changes—ideal for chat apps, dashboards, or notifications.
📂 File Uploads
GraphQL doesn’t support file uploads natively.
Workarounds include the GraphQL multipart request spec (e.g., using
graphql-upload
).REST, on the other hand, supports
multipart/form-data
out of the box, making it simpler for handling files.
Common GraphQL Mistakes
1. Overfetching in Mutations
Fetching unnecessary fields after a mutation—like treating GraphQL as REST.
💡 Only request what’s needed.
2. One Giant Query
Fetching everything in one query leads to performance issues and tight coupling.
💡 Break queries into manageable parts and use pagination.
3. Ignoring Partial Errors
GraphQL can return data and errors together.
💡 Always check the
errors
field, even whendata
is present.
4. Forgetting Aliases
When querying the same field multiple times with different arguments, use aliases to avoid key collisions.
{
user1: user(id: 1) { name }
user2: user(id: 2) { name }
}
5. Skipping Input Validation
GraphQL schemas ensure shape, but not business logic.
💡 Validate inputs manually or via middleware.
6. Kitchen Sink Queries
Stuffing unrelated fields into a single query makes them unreadable and inefficient.
💡 Keep queries focused and modular.
7. N+1 Query Problem
Resolvers hitting the DB repeatedly for nested fields.
💡 Use batching tools like DataLoader to reduce redundant DB calls.
8. Field Versioning (_v2
)
Avoid adding version numbers in field names.
💡 Use GraphQL’s deprecation mechanism instead.
When Should You Use GraphQL?
✅ Use GraphQL If:
You need flexible and efficient data fetching
Your frontend changes frequently
You want to reduce versioning overhead
Your app needs real-time updates
You aggregate data from multiple services
🚫 Avoid GraphQL If:
You only need simple CRUD endpoints
You require native file uploads
You rely heavily on HTTP caching/CDNs
Your team lacks GraphQL experience
You need robust HTTP error semantics
Next-Level GraphQL: Federation
GraphQL Federation is a modern architecture for composing multiple GraphQL services into a single unified graph. Instead of having a single monolithic GraphQL server, you can split your schema across multiple subgraphs—each responsible for a specific domain (e.g., users, products, orders).
These subgraphs are stitched together by a central GraphQL Gateway, which:
Orchestrates requests to appropriate subgraphs
Handles authorization and authentication
Exposes a single unified schema to clients
This enables better scalability, decoupling, and domain ownership. Teams can build and deploy subgraphs independently while still contributing to the same unified API.
🚀 Federation takes GraphQL to the enterprise level—ideal for large organizations with many teams working on different services.
Subscribe to my newsletter
Read articles from Taufik Rahadi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Taufik Rahadi
Taufik Rahadi
Hey there! I'm your friendly neighborhood software engineer, fueled by strong coffee, epic tunes, and an unending quest for clean code (and cat cuddles, obviously). When I'm not busy wrangling GraphQL, REST, gRPC, and microservices into submission, you can usually find me whipping up something delicious in the kitchen for my amazing wife or diving headfirst into the wild world of AI. I'm all about pushing the boundaries of what's possible in tech and sharing every 'aha!' moment along the way. Stick around, it's gonna be a fun ride.