REST vs GraphQL
General information
CRITERIA
REST
GraphQL
Overview
Due to its design REST service puts all heavy lifting of managing data relations on client side. At the same time server forces clients to consume the size & shape of data it determined not concerning of particular need.
GraphQL service takes the heavy lifting of managing data relations on itself, becoming more flexible & adaptive to any possible API consumer. Client side only decides which data size & shape it needs at the moment & receives exactly it.
General Summary
Pros:
Easy & fast to set up & see first results (short-term win);
A lot of recipes & best practices (error handling, caching, security etc.) due to maturity of the approach;
Cons:
Low performance for clients due to overfetching, additional network roundtrips;
Less predictable & more error prone for clients due to the fact that type checking & introspection are not mandatory;
Harder to maintain & extend, keep in ideologically pure state;
Pros:
Flexible to changes & easily adaptive to any possible API consumer (long-term win);
Provides better client experience due to network performance;
More predictable due to strict type checking & built-in retrospection;
Cons:
At the moment may not have mature solutions for widely known problems (error handling, caching, security etc.), which can turn out to reinventing the wheel;
Requires more time to set up & learn;
Architecture
Endpoint is the identity of a resource. Server determines shape & size of the resource to be sent to client.
REST API provides a list of endpoints. Different HTTP verbs as GET, POST, PUT, DELETE, PATCH are used to describe client-server communications.
API requests are handled by route handling functions that are matched by URL path & HTTP verb. Result, produced by a function is serialized & sent back to client with appropriate headers & HTTP status codes.
Resource is described in GraphQL schema with the help of 'types'. The client is free to decide which & how many data to retrieve at once.
GraphQL API only has one endpoint, usually '/graphql'. Additionally, it only takes one HTTP method: POST (there's an option to enable GET too).
GraphQL server receives a request with 'query', describing what data is needed. Appropriate resolvers then are called to fulfill each field in a query. The result is combined together & sent back to client.
Authorization
Request level
Field level
Error handling
REST API relies on widely spread http error conventions, which doesn't change significantly from service to service.
Mostly errors occur at request level - the whole request is failed in case of any error.
Field level errors can be implemented additionally on client-server agreement.
GraphQL API uses custom solutions for error handling, which heavily rely on framework that is used & local error handling convention between client & server side. Error handling can differ a lot from service to service.
Errors are added as an additional array in response from server. HTTP statuses are not used.
Both request level errors & field level errors can occur. That means that requested data can be returned partially, because some of the fields can be resolved, but some are not because of error.
Security
Commonly known types of threats that should be handled in REST API:
injection attacks,
DoS,
broken authentication,
sensitive data exposure,
broken access control,
parameter tampering,
Man-in-the-middle
etc
GraphQL is just a layer, no protection is provided from the box. All the threats that are usual for REST API can occur here as well. Still they can have GraphQL specificity e.g.:
Injection attacks can be caused by not properly sanitized query fields
DoS: deep queries can consume all server resources; complex queries can add additional load on database. As an approach query depth limiting & query cost analysis can be added;
Ecosystem
REST service has a large amount of frameworks for back-end side, no need in any additional solutions from front-end side
GraphQL service strongly depends on supporting frameworks both for front-end & back-end side, the variety of which isn't so large at the moment
Common pros and cons
REST
GraphQL
Better:
Easier cache handling
Less front-end tooling is required
Easier mime-types support
Lower learning curve
Larger community
Higher cloud support
Worse:
Lower flexibility
Worse performance
Harder versioning support
Harder introspection
Worse type checking
Better:
Higher flexibility
Better performance
Easier versioning support
Easier introspection
Better type checking
Worse:
Harder cache handling
More front-end tooling is required
Harder mime-types support
Higher learning curve
Smaller community
Lower cloud support
Detailed pros and cons
CRITERIA
REST
GraphQL
Flexibility
LOWER
Due to its design & philosophy REST API is not so easy to adapt for constantly changing client needs or for several clients at once.
That's why client side is responsible for creating additional logic for managing data relations (e.g.in order to get a comment client goes for all videos => gets video by id => gets its comments => gets comment by id). What turns out into overfetching & additional network roundtrips to retrieve all needed data.
HIGHER
GraphQL API is more flexible for different types of consumers due to its ability to serve exact data that each client needs. It reveals client side from additional logic on managing data relations & making additional network calls.
Performance
WORSE
Common performance concerns:
overfething for client side;
underfetching & additional roundtrips for client side;
BETTER
Common performance concerns:
too deep queries - can be managed by maximum query depth validator;
too complex queries - can be managed by query complexity validator;
N +1 problem - can be managed with batching technique;
Also query batching & deduplication techniques can be applied from client side to even more reduce the amount of network roundtrips.
Cache handling
EASIER
It's simpler to start with caching for REST API because:
http caching is out of the box & requires minimum server configuration;
tool-based caching (CDNs, in-memory & distributed caches) is widely spread, has wide variety of mature options;
doesn't need any additional effort from front-end side;
HARDER
It's harder to start with caching for GraphQL API because:
only tool-based caching (CDNs, in-memory & distributed caches) approach;
front-end effort might be needed;
Front-end tooling
LESS
Communication to REST service doesn't force any specific client architecture/framework
MORE
Communication to GraphQL service forces client to use specific architecture / frameworks (e.g. Relay, Apollo).
Versioning support
HARDER
REST service provides API level versioning. Each version should be handled separately, clients should switch all requests at once in order to migrate to new version.
EASIER
GraphQL service has field level versioning (unused fields are marked as deprecated). Clients can switch to new fields one by one, no need to do everything at once. Also a warning will be received in case of usage any deprecated field.
Introspection
HARDER
manually created API documentation which can be not relevant due to over time changes. Also it needs to be supported for all API versions;
tool based solutions (e.g. Swagger) that need manual set up;
EASIER
out of the box introspection is provided (GraphiQL);
advanced tools can be configured additionally (e.g. Insomnia);
Type checking
WORSE
Static type checking can be added during development. No data type checking in the run-time.
Exists mostly as a good will convention & doesn't guarantee the clients that the service is strictly following the types, which may cause bugs appearing at the very late stages of testing or in production.
BETTER
GraphQL heavily relies on strict data typing, there's no way to resolve types that are not declared in the schema otherwise the request will fail.
That guarantees the clients that all the types are strictly followed, type related bugs usually can be found during the development or at early stages of testing.
Supported mime-types
EASIER
Natural support for any type of data ,like multipart-form-data, application/octet-stream etc
HARDER
For not JSON data GraphQL needs additional configuration or workarounds
Learning curve
LOWER
Doesn't require any specific tool knowledge.
Optionally any frameworks, Typescript or any type checking tool.
HIGHER
Minimal knowledge includes: GraphQL query language, framework for building the API (e.g. Apollo), Typescript or any type checking tool.
Community
LARGER
Due to the fact that REST was the leading approach for building services for more than 10 years already, the community is very large, having accumulated a lot of recipes & best practices for most of the issues. Common problems & bottlenecks are well known. A lot of mature frameworks.
SMALLER
Due to novelty of the approach, the community isn't so large at the moment, new bottlenecks & problems can be found during development, which can or can't have any mature solutions & approaches. Best practices & commonly used recipes are in process of accumulation.
Cloud support
HIGHER
All cloud providers have hosted REST API service. The level of customization and additional features may differ, but it is always there.
LOWER
Only AWS has hosted GraphQL API solution (didn't find GCP or Azure having such service, but maybe I mis-googled it?) - AppSync, which also provides tooling for FE, mobile, and desktop clients.
All other cloud providers require deployment of a separate application or having GraphQL support built in BE application itself.
Last updated
Was this helpful?