Skip to content
TBH
Back to blog
January 9, 20266 min read

REST vs GraphQL: You Probably Don't Need GraphQL

GraphQL was launched by Facebook in 2015 and has since been the "modern" choice for API design. But after building APIs in both paradigms, our honest assessment is: most projects don't need GraphQL.

What's the difference?

REST: Resource-based

REST exposes endpoints for each resource:

GET/api/users/123
POST/api/users
PUT/api/users/123
DELETE/api/users/123
GET/api/users/123/orders

The server determines which fields are returned.

GraphQL: Query-based

GraphQL has one endpoint where the client specifies exactly what it wants:

query {
  user(id: 123) {
    name
    email
    orders {
      id
      total
    }
  }
}

The client determines the structure.

When GraphQL makes sense

GraphQL solves real problems - just not the problems you probably have.

Use GraphQL when:

1. You have many different clients with vastly different data needs

Facebook has iOS, Android, web, React Native, embedded devices - all with different screens and data needs. One flexible API makes sense.

Do you have that? Probably not. Most have one webapp and maybe one mobile app.

2. You have deeply nested, relational data with complex queries

Social networks, content management systems, or e-commerce with thousands of product variants.

3. Your frontend team wants full control over data

GraphQL gives frontend developers freedom to fetch exactly what they need without waiting for backend changes.

4. You have a dedicated API team

GraphQL requires more infrastructure: schema management, query complexity analysis, caching strategy, performance monitoring.

Use REST when:

1. You're building a standard webapp or mobile app

CRUD operations, user management, simple relations. REST does it with less complexity.

2. You have one or two client types

If all your clients use the same data roughly the same way, GraphQL solves a problem you don't have.

3. Caching is important

REST's HTTP-based caching (CDN, browser cache, etags) works out-of-the-box. GraphQL's POST requests don't cache automatically.

4. Your team is small

GraphQL has a learning curve and maintenance costs. Small teams get more out of simple REST.

The hidden costs of GraphQL

1. N+1 Problem

The classic GraphQL trap:

query {
  users {
    name
    posts {
      title
    }
  }
}

Without DataLoader, this makes one query for users + one query per user for posts. 100 users = 101 database queries.

Solution: DataLoader, but that's extra complexity you have to build and maintain.

2. Caching is hard

REST:

GET/api/users/123

Browser and CDN cache automatically with Cache-Control headers.

GraphQL: All requests are POST to the same endpoint. You need to implement:

  • Persisted queries
  • Apollo Client cache
  • Server-side caching with Redis
  • Cache invalidation strategy

3. Rate limiting and security

REST: Limit requests per endpoint. Simple.

GraphQL: A single query can be cheap or extremely expensive:

query {
  users {
    posts {
      comments {
        author {
          posts {
            comments {
              # Nested doom
            }
          }
        }
      }
    }
  }
}

You need to implement query depth limiting, complexity analysis, and timeout handling.

4. Error handling

REST: HTTP status codes. 404 = not found. 401 = unauthorized. Everyone understands it.

GraphQL: Everything returns 200 OK. Errors are hidden in response body under errors array. You have to parse and handle it yourself.

5. Tooling and debugging

REST: Any HTTP client works. curl, Postman, browser DevTools.

GraphQL: You need specialized tools like GraphiQL or Apollo Studio to be productive.

Performance comparison

AspectRESTGraphQL
Over-fetchingYes, server decidesNo, client decides
Under-fetchingYes, multiple requestsNo, one request
CachingBuilt into HTTPMust be implemented
Request overheadMinimalQuery parsing + validation
N+1 queriesRare problemCommon problem

Over-fetching (getting too much data) is GraphQL's main argument. But in practice:

  • JSON parsing is fast
  • Gzip compresses well
  • You can make separate REST endpoints for specific views

Our recommendation

Start with REST. Always.

  1. Simple to understand - everyone knows HTTP verbs and status codes
  2. Simple to cache - CDN and browser cache work automatically
  3. Simple to secure - rate limiting per endpoint
  4. Simple to document - OpenAPI/Swagger is industry standard
  5. Simple to debug - curl and browser DevTools

Consider GraphQL when:

  • You have 3+ different client platforms with different data needs
  • Your frontend team is constantly blocked by backend changes
  • You have a dedicated API team to maintain the infrastructure
  • Over-fetching is a measurable performance problem, not theoretical

The BFF pattern: Best of both worlds

Many teams use Backend for Frontend (BFF) instead of GraphQL:

Mobile App  → Mobile BFF  → Services
Web App     → Web BFF     → Services

Each BFF is a thin REST API that aggregates exactly the data the client needs. You get:

  • Client-specific data without GraphQL complexity
  • Simple HTTP caching
  • No new query language to learn

Conclusion

GraphQL is a fantastic tool - for the problems it solves. But "everyone uses it" is not a good reason to choose it.

Ask yourself:

  • Do I really have many different clients with vastly different needs?
  • Is over-fetching a measurable problem in my app?
  • Do I have resources to build and maintain GraphQL infrastructure?

If the answer is no, then REST is the right choice. It's not old-fashioned - it's pragmatic.

See what we have built

Nordvec, nævn.dk, Matematik i Måneby in the browser, Semantika and open source.

See the projects