Topic Overview

REST vs GraphQL: Choosing the Right API Style

Choose REST or GraphQL: caching, performance, tooling, versioning, and when each approach fits best.

26 min read

REST vs GraphQL

Why Engineers Care About This

REST and GraphQL are different approaches to API design. REST uses multiple endpoints, each returning fixed data structures. GraphQL uses a single endpoint, with clients specifying exactly what data they need. Both solve real problems, but they solve different problems. Choosing the wrong one creates complexity, poor performance, or developer frustration.

When your API has too many endpoints, or clients fetch too much data, or you need flexible queries, you're hitting problems that REST or GraphQL might solve. These problems compound. Too many endpoints create maintenance burden. Over-fetching wastes bandwidth and slows responses. Under-fetching requires multiple requests. Understanding when to use REST vs GraphQL helps you design APIs that solve these problems.

In interviews, when someone asks "REST or GraphQL?", they're really asking: "Do you understand the trade-offs? Do you know when each is appropriate? Do you understand that they're not mutually exclusive?" Most engineers don't. They choose based on trends ("GraphQL is modern") or familiarity ("I know REST"), not based on requirements.

Core Intuitions You Must Build

  • REST is about resources, GraphQL is about queries. REST models your domain as resources (users, orders, products) and uses HTTP methods to operate on them. GraphQL models your domain as a graph of data and lets clients query exactly what they need. REST is simpler (standard HTTP, caching works well) but can require multiple requests. GraphQL is more flexible (single request, exact data) but is more complex (query language, resolvers, N+1 problems).

  • REST scales with HTTP, GraphQL scales with resolvers. REST leverages HTTP's built-in features (caching, status codes, methods). HTTP caches work out of the box. Load balancers understand HTTP. GraphQL requires custom caching (query-based, not URL-based) and custom resolvers (functions that fetch data for each field). REST's scaling comes from HTTP infrastructure. GraphQL's scaling comes from resolver optimization.

  • Over-fetching vs under-fetching is the key trade-off. REST endpoints return fixed data structures. If you need more data, you make more requests (under-fetching). If you need less data, you still get everything (over-fetching). GraphQL lets clients specify exactly what they need, avoiding both problems. But GraphQL's flexibility comes with complexity—you must optimize resolvers to avoid N+1 queries.

  • REST is better for caching, GraphQL is better for flexibility. REST's URL-based caching works well—same URL = same response, cache it. GraphQL's query-based caching is harder—same query = same response, but queries can vary slightly (different fields, different arguments). REST's caching is simpler and more effective. GraphQL's flexibility is more powerful but harder to cache.

  • N+1 queries are GraphQL's biggest problem. GraphQL resolvers are called for each field. If a query requests users and their orders, the users resolver fetches users, then the orders resolver is called for each user (N+1 queries). Solution: use DataLoader (batches and caches resolver calls) or optimize resolvers to batch queries. REST doesn't have this problem (you control the query in the endpoint).

  • REST and GraphQL can coexist. You don't have to choose one. Use REST for simple CRUD operations (create user, get user, update user). Use GraphQL for complex queries (get user with orders, products, and reviews in one request). Many systems use both—REST for standard operations, GraphQL for flexible queries. Don't think of them as mutually exclusive.

Subtopics (Taught Through Real Scenarios)

When to Use REST

What people usually get wrong:

Engineers often think "GraphQL is modern, so use GraphQL." But REST is simpler and sufficient for many use cases. Use REST when you have simple CRUD operations, standard data structures, or need HTTP caching. REST's simplicity is its strength—standard HTTP, easy to understand, works with existing tools (browsers, caches, load balancers). Don't use GraphQL just because it's "modern"—use it when you need its flexibility.

How this breaks systems in the real world:

A team chose GraphQL for a simple CRUD API (create, read, update, delete users). They didn't need flexible queries—clients always needed the same data. GraphQL added complexity (query language, resolvers, schema) without providing benefits. The API was harder to maintain and slower (GraphQL overhead) than REST would have been. The fix? Use REST for simple CRUD. But the real lesson is: choose based on requirements, not trends. REST is simpler and sufficient for many use cases.

What interviewers are really listening for:

They want to hear you talk about when REST is appropriate (simple CRUD, standard data, HTTP caching). Junior engineers say "GraphQL is modern, use GraphQL." Senior engineers say "use REST for simple CRUD operations, standard data structures, and when you need HTTP caching—REST's simplicity is its strength." They're testing whether you understand that REST is still appropriate for many use cases.

When to Use GraphQL

What people usually get wrong:

Engineers often avoid GraphQL because it's "too complex." But GraphQL solves real problems: over-fetching (getting more data than needed), under-fetching (needing multiple requests), and API versioning (adding fields doesn't break clients). Use GraphQL when you have complex queries, multiple clients with different data needs, or need to reduce over-fetching. GraphQL's flexibility is its strength—clients get exactly what they need.

How this breaks systems in the real world:

A mobile app needed user data with orders, products, and reviews. With REST, this required 4 requests (get user, get orders, get products, get reviews). Each request added latency. The app was slow. With GraphQL, this required 1 request (query user with orders, products, reviews). The app was faster. The fix? Use GraphQL for complex queries that need data from multiple resources. But the real lesson is: GraphQL's flexibility solves real problems—use it when you need it.

What interviewers are really listening for:

They want to hear you talk about when GraphQL is appropriate (complex queries, multiple clients, reducing over-fetching). Junior engineers say "GraphQL is too complex, avoid it." Senior engineers say "use GraphQL for complex queries, multiple clients with different data needs, or when you need to reduce over-fetching—GraphQL's flexibility is its strength." They're testing whether you understand that GraphQL solves real problems.

N+1 Query Problem

What people usually get wrong:

Engineers often implement GraphQL resolvers naively—each resolver makes a database query. This works for simple queries, but causes N+1 queries for nested data. If a query requests users and their orders, the users resolver fetches users (1 query), then the orders resolver is called for each user (N queries). Total: 1 + N queries. Solution: use DataLoader (batches resolver calls) or optimize resolvers to batch queries.

How this breaks systems in the real world:

A GraphQL API had resolvers that made individual database queries. A query requesting 100 users with their orders made 1 query for users, then 100 queries for orders (one per user). Total: 101 queries. The database was overloaded, responses were slow. The fix? Use DataLoader—it batches resolver calls, so 100 order requests become 1 batched query. But the real lesson is: GraphQL's flexibility requires resolver optimization. Naive resolvers cause N+1 queries.

What interviewers are really listening for:

They want to hear you talk about N+1 queries, DataLoader, and resolver optimization. Junior engineers say "GraphQL resolvers just fetch data." Senior engineers say "naive GraphQL resolvers cause N+1 queries—use DataLoader to batch resolver calls or optimize resolvers to batch queries." They're testing whether you understand that GraphQL's flexibility requires careful implementation.

Caching Strategies

What people usually get wrong:

Engineers often think "GraphQL can't be cached" or "REST caching is automatic." But both can be cached, just differently. REST's URL-based caching works well—same URL = same response, cache it. GraphQL's query-based caching is harder—same query = same response, but queries can vary slightly. Use HTTP caching for REST (Cache-Control headers). Use query-based caching for GraphQL (cache query results by query string and variables). Both work, but REST's caching is simpler.

How this breaks systems in the real world:

A GraphQL API didn't implement caching. Every request executed queries, even for frequently accessed data. The database was overloaded, responses were slow. The fix? Implement query-based caching—cache query results by query string and variables. But the real lesson is: GraphQL requires custom caching. REST's HTTP caching works out of the box, but GraphQL's caching requires implementation.

What interviewers are really listening for:

They want to hear you talk about caching strategies for REST vs GraphQL. Junior engineers say "GraphQL can't be cached" or "REST caching is automatic." Senior engineers say "REST uses HTTP caching (Cache-Control headers), GraphQL uses query-based caching (cache by query string and variables)—both work, but REST's caching is simpler." They're testing whether you understand that both can be cached, just differently.


  • REST is about resources, GraphQL is about queries—choose based on your domain model
  • REST is simpler, GraphQL is more flexible—simplicity vs flexibility trade-off
  • REST scales with HTTP, GraphQL scales with resolvers—different scaling strategies
  • Over-fetching vs under-fetching—REST can do both, GraphQL avoids both
  • N+1 queries are GraphQL's biggest problem—use DataLoader or optimize resolvers
  • REST caching is simpler, GraphQL caching requires implementation—HTTP caching vs query-based caching
  • REST and GraphQL can coexist—use REST for simple CRUD, GraphQL for complex queries

Key Takeaways

REST is about resources, GraphQL is about queries—choose based on your domain model

REST is simpler, GraphQL is more flexible—simplicity vs flexibility trade-off

REST scales with HTTP, GraphQL scales with resolvers—different scaling strategies

Over-fetching vs under-fetching—REST can do both, GraphQL avoids both

N+1 queries are GraphQL's biggest problem—use DataLoader or optimize resolvers

REST caching is simpler, GraphQL caching requires implementation—HTTP caching vs query-based caching

REST and GraphQL can coexist—use REST for simple CRUD, GraphQL for complex queries


About the author

InterviewCrafted helps you master system design with patience. We believe in curiosity-led engineering, reflective writing, and designing systems that make future changes feel calm.