Amplication highlights the 7 key differences between GraphQL and Rest APIs. As a backend engineer, you may be used to Rest. However, GraphQL has some advantages it's worth checking out, such as the concrete solutions defined in its specifications that can solve recurring problems encountered in standard API implementations.
Then again, depending on your use cases, REST could be could still be a better solution, because of its flexibility and light weight.
In this article we will compare the major features of REST and GraphQL, to help you decide the best solution for your next API project. Even when maintaining existing APIs, the GraphQL concept might offer benefits. So, is it worth using GraphQL? Let’s find out!
1. Level of abstraction
Comparing REST and GraphQL is an apples and oranges kind of comparison. While REST is an architectural style for building APIs, GraphQL is a specification. This difference makes GraphQL much more opinionated and REST more flexible.
Being more opinionated leads to GraphQL APIs being more similar on average than REST APIs. So, a developer that has worked with many GraphQL APIs in the past might re-use more of their skills and onboard quicker when starting on a new GraphQL project. REST APIs, on the other hand, can be pretty diverse and might lead to a more extended onboarding for a developer, even if they already worked with REST in the past.
We should keep in mind that specification and architectural styles, while existing on different levels of abstraction, are both still very high levels of abstraction. So, while REST might be more abstract than GraphQL, they both can be used very flexibly. For example, GraphQL forces access via a pre-defined query language, and REST doesn’t, but we can still choose how to paginate results with GraphQL as we can with REST.
2. Static vs. dynamic typing
From the fact that GraphQL is a specification follows that it comes with more predefined framework conditions. One of these is static typing, which can be implemented in REST but is mandatory in GraphQL and enforced by GraphQL’s requirement to use its query language. This means we have to define a static schema for every GraphQL API, including types for every piece of data we want to deliver.
On the one hand, this slows GraphQL development down because you can’t just pipe data from the source directly to the client. On the other hand, it enables the GraphQL ecosystem to offer sophisticated code generators out of the box.
If you’re using a statically typed language, like Java or TypeScript, to build your API backend, chances are good you can use one of these generators. If we want such features for a REST API, we have to implement them ourselves or use third-party tools.
One such tool is Amplication. It allows us to define a REST or GraphQL API with a UI and generates a Node.js application for us. Sure, the generated REST API code might be more opinionated than when you write one from scratch, but it also makes it more accessible for your team.
3. The difference between GraphQL and REST API response formats
We can use REST and GraphQL with different serialization formats, like JSON or XML. We can even make up our own optimized format in textual or binary form.
The REST response format can be completely customized. If we don’t need enums or maps, it allows us to use structures that don’t support them but have other benefits like better compression or faster serialization performance.
GraphQL is a bit stricter in its requirements of the format. The format we choose has to support maps, lists, strings, null, boolean, ints, floats, and enums. Also, the field-ordering in maps should match the order of the fields in the request. This is, again, less flexible, but the missing flexibility might not impact you at all in the end. In software development, stricter boundaries are usually helpful in the long run, even if it doesn’t seem like it at first. If your project grows, less flexibility leads to variation in implementation, which is easier for your team to maintain.
4. Impendence mismatch
When developing software, it’s always a problem to convert one data structure into another. This is due to the fact that data structures inside a program have different requirements than inside a database. When you load data from a SQL database into object-oriented software, you have to convert tables and rows to objects, leading to data duplication. Sometimes there are multiple different ways of doing this conversion, all with their own pros and cons.
This is also the case when delivering data from storage via an API. Here, we have to convert from the storage format to the API serialization format and then to the data structures in our application.
Since REST is more flexible, it’s often easier to tailor an API endpoint directly to the access pattern of the database. These customized endpoints can improve performance, but they also couple the API more to data storage, which can be harmful in the long run.
If you have an app screen or web page that loads data from multiple endpoints, the overhead of all these requests can become too much to bear, so writing a custom endpoint for that specific use case is a way to lower the latency. But a custom endpoint will then be tightly coupled with the frontend.
The same goes for directly exposing storage schema as REST resources. It’s a straightforward way to implement an API if you don’t have any usage data yet, but it will also couple your API to the storage type you’re using.
GraphQL sometimes requires crutches like the data-loader pattern to merge multiple data types split by the schema into one database request. But it also decouples the data storage from the API implementation, which makes changing the database simpler in the future.
The GraphQL schema language follows a graph approach to data modeling, hence the name GraphQL. In most cases, you won’t have a graph database directly mapped to this schema, so you need to convert your storage schema to the GraphQL schema. This is more work initially but keeps your storage decoupled from your API implementation and, in turn, allows you to replace the storage more easily later on.
5. HTTP focus
REST heavily focuses on HTTP, encouraging multiple endpoints, different HTTP verbs, and standardized status codes. GraphQL, meanwhile, uses one endpoint and only the POST verb when implemented for HTTP. It doesn’t require HTTP at all in the specification.
While GraphQL APIs usually use HTTP, the specification is completely detached. GraphQL solves all of its requirements within its response format, which, as we saw in point three, is a bit more strictly defined than with REST.
If you look into a GraphQL response, you usually find all the information you need to debug it, including metadata and errors. This makes implementing GraphQL for another protocol a bit simpler; we are good to go if we can use a serialization format that conforms to GraphQL’s requirements.
REST tries to use many standardized HTTP features, which leads to information ending up all over the place. Projecting these features into a different protocol is thus a bit more cumbersome.
6. Real-time subscriptions
GraphQL comes with real-time features baked right in. You can subscribe to a GraphQL endpoint and get changes from the server delivered via a more flexible connection like WebSockets. This allows the client to be notified of changes on the backend project without manually requesting them.
A REST API can be built on top of WebSockets, but again, the REST architectural style doesn’t give you any guardrails here; you’re on your own, which can be a good thing or a bad thing depending on what you want to build.
7. GraphQL vs REST APIs - Enterprise support
REST is much older than GraphQL; it was first mentioned in Roy Fielding’s doctoral dissertation in the year 2000. GraphQL development, on the other hand, started in 2012 and was released in 2015. This means REST-style APIs have more extensive support from big enterprises, which are prone to moving slowly in technology adoption.
If you have to integrate with a big enterprise, chances are you have to follow their requirements for API design, so you’ll probably end up with REST instead of GraphQL. That means, even if you don’t need REST’s flexibility, you will have to deal with the extra work it requires.
But again, a tool like Amplication can help get your REST development experience closer to that of GraphQL.
REST and GraphQL are the leading players in the API space, and both have their pros and cons.
REST is very flexible, and if we have niche requirements, the GraphQL spec might hamper us in building the best API for our use case.
GraphQL is much more opinionated, as it comes with a concrete specification. This makes the GraphQL API landscape much more homogenous in practice and allows for the onboarding of developers who have worked with other GraphQL APIs more quickly.
If you want to test your GraphQL skills, check out our tutorial on how to build an e-commerce application using GraphQL, NestJS, and Prisma.
A tool like Amplication smoothes out these differences between GraphQL and REST APIs a bit so you can focus on your features and not get stuck in the architecture phase for too long. It also generates simple TypeScript code, so if you outgrow it in the future, you can still use the code files generated later on as well.
Amplication can generate both REST and GraphQL APIs for you, allowing you to easily compare the two approaches. Generate both for one project, and check for yourself which one best fits your needs.