Beyond the Hype
The GraphQL vs REST debate has become one of the most polarized discussions in web development. GraphQL advocates argue that REST is outdated and inflexible. REST defenders argue that GraphQL adds unnecessary complexity. Both sides are partially right and partially wrong.
At StrikingWeb, we use both GraphQL and REST in production, choosing based on the specific requirements of each project. This post explains the genuine trade-offs and provides practical guidance for making the right choice.
REST — The Established Standard
REST (Representational State Transfer) organizes APIs around resources. Each resource (user, product, order) has a URL, and you interact with resources using HTTP methods (GET, POST, PUT, DELETE). REST is the dominant API architecture and has been for over a decade.
GET /api/users/123 → Fetch user 123
POST /api/users → Create a new user
PUT /api/users/123 → Update user 123
DELETE /api/users/123 → Delete user 123
GET /api/users/123/orders → Fetch user 123's orders
REST Strengths
- Simplicity: REST maps naturally to HTTP concepts that every web developer understands. The learning curve is minimal.
- HTTP caching: REST responses can be cached at every layer — browser, CDN, reverse proxy — using standard HTTP cache headers. This is arguably REST's most significant advantage.
- Statelessness: Each REST request contains all the information needed to process it. This makes scaling straightforward.
- Tooling maturity: Decades of tooling exists for REST — API gateways, documentation generators (OpenAPI/Swagger), monitoring tools, and testing frameworks.
REST Weaknesses
- Over-fetching: REST endpoints return fixed data structures. If you need only a user's name and email, you still receive the entire user object with all its fields.
- Under-fetching: Displaying a page that combines data from multiple resources (user profile with orders and reviews) requires multiple API calls, creating a waterfall of requests.
- Endpoint proliferation: As your application grows, the number of endpoints multiplies. Different UI views may need slightly different data, leading to one-off endpoints or over-generalized responses.
GraphQL — The Flexible Alternative
GraphQL, developed by Facebook and released publicly in 2015, takes a fundamentally different approach. Instead of multiple endpoints, there is a single endpoint that accepts queries describing exactly what data you need. The server responds with exactly that data — nothing more, nothing less.
# A single query fetches everything the UI needs
query UserProfile {
user(id: "123") {
name
email
avatar
orders(last: 5) {
id
total
status
items {
product {
name
price
}
}
}
reviews(last: 3) {
rating
comment
product {
name
}
}
}
}
GraphQL Strengths
- Query flexibility: Clients request exactly the data they need. No over-fetching, no under-fetching. Different UI views can fetch different data shapes from the same API.
- Single request: A single GraphQL query can aggregate data from multiple resources that would require several REST calls. This reduces network round trips, which is particularly valuable on mobile networks.
- Strong typing: The GraphQL schema defines every type, field, and relationship. This serves as always-up-to-date API documentation and enables powerful developer tooling (autocompletion, validation, code generation).
- Versioning not needed: GraphQL APIs evolve by adding new fields and types. Since clients request only the fields they use, new additions do not break existing clients. There is no need for /v1, /v2 versioning.
GraphQL Weaknesses
- Caching complexity: Because all requests go to a single endpoint via POST, standard HTTP caching does not work. You need application-level caching with tools like Apollo Client or Relay, which adds complexity.
- Query complexity attacks: Malicious clients can construct deeply nested queries that overwhelm your server. You need to implement query depth limiting, cost analysis, and rate limiting based on query complexity.
- Learning curve: GraphQL requires learning a new query language, schema design patterns, and resolver architecture. The mental model is different from REST.
- File uploads: GraphQL does not have a built-in specification for file uploads. While solutions exist (multipart request specification), they are not as straightforward as REST file uploads.
- N+1 query problem: Naive resolver implementations can trigger one database query per item in a list, leading to significant performance issues. Solutions like DataLoader exist but must be implemented deliberately.
When to Choose REST
Based on our experience, REST is the better choice when:
- Your API is simple: CRUD operations on a small number of resources are well-served by REST without the overhead of GraphQL.
- HTTP caching is critical: If your API serves public data that benefits from CDN caching (product catalogs, content APIs), REST's native HTTP caching is a significant advantage.
- You are building a public API: External developers are more likely to be familiar with REST, and the simpler model reduces integration friction.
- Your team is small and needs to move fast: REST requires less upfront design and tooling. You can build a REST API with any HTTP framework in any language without additional dependencies.
- File-heavy operations: APIs that primarily deal with file uploads and downloads are better served by REST.
When to Choose GraphQL
GraphQL is the better choice when:
- Multiple clients need different data: If your API serves a web app, mobile app, and admin dashboard — each needing different data from the same resources — GraphQL's query flexibility eliminates the need for client-specific endpoints.
- Your data model is complex and interconnected: When your UI needs to traverse relationships (user -> orders -> products -> reviews), GraphQL's ability to fetch nested data in a single request is genuinely superior.
- Rapid frontend iteration: When the frontend team needs to iterate quickly on UI designs, GraphQL lets them change data requirements without waiting for backend endpoint changes.
- You want strong API contracts: The GraphQL schema provides a machine-readable contract between frontend and backend, enabling code generation, automatic validation, and excellent developer tooling.
The Hybrid Approach
In practice, you do not have to choose exclusively. Several of our projects use both:
- GraphQL for the primary application API: The frontend queries GraphQL for complex, interconnected data.
- REST for webhooks and integrations: External systems send and receive data through simple REST endpoints.
- REST for file operations: Uploads and downloads use standard REST endpoints.
- REST for health checks and operational endpoints: Simple GET endpoints for monitoring and status checks.
The best API architecture is the one that serves your specific needs with the least friction. Do not adopt GraphQL because it is trendy, and do not dismiss it because REST is familiar. Evaluate the trade-offs for your specific use case, team, and business requirements.
Our Recommendation
If you are building an application with a rich, data-heavy frontend that needs to display interconnected data from multiple sources, GraphQL will save you significant development time. If you are building a simpler API with straightforward CRUD operations and need maximum caching performance, REST is the right choice. At StrikingWeb, we help clients evaluate these trade-offs and design API architectures that serve their applications well.