GraphQL is unarguably a very powerful tool that will allow you to have more control when you need to access data within a front-end application. There are countless success stories of large organizations like Shopify, GitHub, and Facebook, who have implemented GraphQL successfully.
Implementing GraphQL can undoubtedly help teams to deploy features quicker as well as fine-tune performance, however, just because GraphQL can benefit certain projects that does not mean that you will automatically reap the same benefits on your next CMS project by moving away from REST
When you need to work with pretty much the majority of headless CMS within the marketplace today, you will have the option to consume content in your front end either via GraphQL or REST API. As GraphQL is the newer of these two technologies you will likely find more blogs and videos advocating GraphQL as our new development saviour compared to good old REST. You can prove this fact for yourself now by performing a quick Google search for GraphQL and CMS.
GraphQL definitely has benefits, however, just because something is newer that does not mean that you should automatically switch to it as your defacto standard. For those readers who are newer to GraphQL, I think you will find it useful to have a better appreciation of GraphQL versus REST within the context of a headless CMS project. Read on to learn in what ways GraphQL can improve as well as hinder your next CMS project. By the end of this article, you should have enough information to make an informed decision on which technology is best suited to your next project 🔥🔥🔥
One of the first benefits to consider of switching to GraphQL within your front-end website is improved control. Imagine you want to render some content on your site, however, the content and data you want to render are contained within multiple different data stores.
To access all this data using a REST API, you would either need to call an API end-point that consolidates all this information or, you would need to call multiple API end-points within the execution of the current request.
Instead, if a frontend team has access to a GraphQL layer that contains all the data they need, it is possible for them to write a single GraphQL query and get all the data they may require easily. Being able to write a query in the front end that combine all these data sources in a decoupled way can be extremely useful.
First, by constructing a single query instead of multiple queries your page should load quicker. Secondly, GraphQL allows frontend teams to work in a more independent way. Having access to a GraphQL layer will allow teams to get data in ways that a backend developer may never have considered or intended. REST APIs are handy, however, they have a limit. An end-point can only return data in a format that it was designed to return. As GraphQL works with queries, as long as the data is contained within your GraphQL layer, a frontend team can write a query to access it.
This all sounds great, however, in a CMS project how often do you really need this type of feature? Most headless CMS systems will ship with an SDK and a REST API that allows frontend teams to query for any bit of content that has been created within the CMS. The main purpose of most of the CMS projects that I have personally worked on (over 200 projects) is content-driven. In these types of projects, most pages are simply content pages that are pulled from the CMS. If you can also easily get all the content you need within your front end from a CMS vendor REST APIs and SDK, do you still need GraphQL?
In order to answer this question, we will consider the four most debated arguments that you can find online between the pro-GraphQL and pro-REST API camps. Read on to learn more 🔥🔥🔥
Before we get to these arguments, I do want to debunk one GraphQL myth quickly. That myth is about what GraphQL will replace within your architecture. Occasionally, a few developers newer to GraphQL end up thinking that GraphQL would replace SQL within their architecture, this is definitely not true. Yes, you construct queries with GraphQL, however, these queries are made against your GraphQL layer. Regardless of GraphQL or REST API end-point, you still need to get your data from a data source. On a CMS project, that data source will be a database stored in some flavour of SQL. The thing that GraphQL would replace is the need for making HTTP queries in your backend, got it, good 💥
Frontend Power Vs Architecture Awareness
A trade-off from implementing GraphQL is the need for frontend teams to have an additional understanding of the data architecture. Historically using REST APIs, a frontend developer would not need to understand how the backend data structure was organized. To implement a new feature, all they needed to do was to call an end-point and they would get all the data they needed. If an end-point didn't exist that returned data in the format they needed, a new end-point would need to be built. Depending on the size of a company, sometimes a different backend team might have been responsible for building the new end-point. The benefit of this type of setup is that the front-end team can concentrate on building the front end and not worry too much about how to get the data. The downside is that it introduces a waiting game and an extra dependency on the project. Having to wait on another team to do some work might cause project delays within your project.
GraphQL gives you more access to data in your front end, however, it also abstracts things. When you have access to everything in a flat form, how do you know if your GrapQL queries will end up slowing down your backend? Trying to understand where the code of your GraphQL is slow is much harder compared to calling pre-defined endpoints. If you bump into performance-related GraphQL errors, you will need to read, debug and potentially update backend code regardless.
I saw an article the other week, where a team had moved from a REST API to GraphQL. The REST API made one database transaction per HTTP request, however, when they moved to GraphQL the same query in GraphQL ended up querying the database once per element within a slice. This ended up being something like 100x the amount of traffic being made to the database, which slowed down the whole site 😕
Now my question to you is, within your CMS project, do you think you will need to combine multiple data sources within your GraphQL layer? From m experience, no. Asides from site search, most calls within a CMS project are to get either certain pages by URL, get a bunch of pages by page type, or a bunch of pages in relation to the position of the current page within the website's page hierarchy. In most headless CMS SDKS all this can be done with REST easily.
GraphQL Vs Performance
One of the big allures of using GraphQL is the ability to be very specific in what data is returned to the front end. Consequently, front-end websites that use GraphQL will typically have faster response times when making external calls to get data.
The alternative option is to get your data via a REST API call. When you call a pre-built API, all the data that the API has been designed to return will be passed back to the site, regardless if that data is needed or not. Obviously, being able to only return the data you need in transit will always be quicker, however, in terms of CMS development is this really a big issue?
An important point to consider about performance and web vitals within a website is that typically the worst offender in performance won't be those extra 1 or 2 kilobytes being transmitted. On a CMS project how you write your code, the images that have been added to the page, any external tracking snippets you add to your page, and the overall bundle size will all likely have a much bigger impact on performance compared to the API call to get the data.
GraphQL emerged as a solution to a specific predicament Facebook faced. Facebook needed to migrate its newsfeed without impacting users. GraphQL was not designed with the intention of being the defacto data-access tool for all applications. When you are working on an application that has to process thousands of requests per second, like Facebook, shaving milliseconds off every request is a massive win. Likewise, if you need to change where the underlining data is coming from within your application, being able to hide the migration behind a GraphQL layer is useful.
From my experiences creating CMS-powered websites within enterprise-sized companies, typically you do not hit these types of issues. If you need to change the CMS that is providing the data, you will be forced into rebuilding the end website as well. Too much change will be required throughout the website. Trying to shoehorn an existing site to use a different CMS vendor's schemas is more effort than starting from scratch.
Likewise, on a website, you will not have the same data transaction pressures that you would face in other systems. The main use of GraphQL would be searching content and rendering pages. Accessing pages will normally be via URL, or by content type both of which are simple queries to build. Both of these scenarios can benefit from GrahQL, however, the impact is not as substantial compared to a high transaction type of application.
Another performance factor to take into consideration is the type of rendering that the website uses. If your site uses static site generation, the execution time of your queries is not as important as it will happen offline. Even if you do not use SSG, I would expect all websites that render pages using server-side rendering to make use of HTTP-level caching. This means that the number of transactions back to the CMS should be minimal. If your site is not using a cache, then the size of your API call will definitely not be your biggest issue!
None of this is knocking on GraphQL, however, in terms of performance I think it's fair to say that the benefits GraphQL can provide in this area are not as impressive compared to other types of systems.
GrapQL Vs Content Modeeling
One of the more polarizing points around adopting GraphQL is the trade-off of the added complexity that it brings compared to the overall time it saves the frontend team from being self-reliant. Out of the points raised within this article, this is the most hotly debated one online.
I think the reason for this minor controversy is that the answer is not a binary yes/no that is applicable to every project. The amount of time you may gain or save will be BASED on the complexity of your project.
Being able to query for the exact data you need from the front end is very handy, however, in reality, many CMS projects will only need to render CMS pages and never need to combine data from different sources.
In smaller projects, when a company wants to create a new feature, it can take the same time for a backend team to create a new end-point that exposes the data required by the front end. When using GraphQL, If you are lucky the data required by the new feature might already be accessible via your GraphQL layer, and no additional backend work is required. From my experience, some level of backend work has typically been required to expose some form of additional data.
To get going with GraphQL you will need to install some additional packages like Apollo as a client to talk to GraphQL. Apollo will save you from re-inventing the wheel, however, it is not a trivial package to master. When you decide to use Apollo, everyone on your team will need to learn and master how to use it correctly. This upskilling is typically why it will take longer for a team to learn GraphQL compared to calling a REST API using classic
As GraphQL is based on you building custom queries, you will typically not have the same level of SDK support from your CMS vendor when you go the GraphQl route. In the CMS world, a lot more is left for you as the implementor to build when you follow the GraphQL route. This is all fine, however, in CMS land there is an elephant in the room, content models.
Within a CMS project content is built by content editors. In order to allow content editors to add content you will need to define a bunch of templates/content models. These models will contain instructions on what properties content editors can see and in what format. This is all great, however, if you write bespoke GraphQL queries in your front end based on your content models, what happens if you update the content model within the CMS?
Whenever you update a content model and you use GraphQl any related queries that call that model will break. Often tracking down which areas in your code has broken is not straightforward.
When you query the CMS using a REST API end-point, you will get all the properties related to the content model regardless of the changes you make to that model within the CMS. When using data returned from a REST API, as long as you write some defensive code, your pages can still work even if you rename or delete a property. This is definitely a debatable point if it's good or bad, however, it can be handy!
When you start undertaking the initial content modelling process and you are trying to figure out what needs to be included within your model, GraphQL gives you less flexibility as you will be forced into updating your queries every time you make a change in the CMS.
Take Optimizely as an example. They provide a CMS, an e-commerce solution, a search provider, and a customer data platform. If you were just using their CMS and building a headless brochureware website, I'd say go with REST API. If you were building an e-commerce store that made use of all of their products then GraphQL would be a way better option. Being able to define a single gateway to get all your website's data will be much easier than having to make different API calls to different systems as well as manage different access tokens, etc...
Preview and search
GraphQL solves the challenges of accessing data at scale better than REST, however, it comes with trade-offs. Things that are easy to implement with REST can become a pain to implement with GraphQL. These features include accessing preview CMS content, access control, rate-limiting, request caching, and N + 1 problems.
On a CMS project, one of the biggest challenges you will need to overcome is preview content. Within the CMS itself, you will need a way to allow content editors to view preview and draft content within your headless CMS before it is published to production. This means that you will also need a way to expose the preview content and the production content somehow.
Getting preview content in most headless CMS systems via REST is simple. You add some form of flag or access token to a request and the API will return the preview content. GraphQL can be harder for some CMS systems. BEfore picking GraphQL make sure you can access preview content!
Based on all the above, this is the reason my default choice of data access on a CMS project is good old REST. Combining a CMS vendor's REST API with its SDK will provide all the content access that most projects will need. Using a vendor's SDK will mean that your code will be more standardized and easier to pick up, compared to the alternative of teams needing to understand the data layer first.
In the CMS world, a CMS like Umbraco 12 now ships with a REST API and it's only their SAAS product HeartCore that uses GraphQL. In terms of picking which version to use, I'm hoping it's coming across both solutions will work and both solutions have their pros and cons.
GraphQL benefits become more apparent in high-transaction solutions that need to combine data from multiple sources, or, where the returned data will change a lot. Most CMS do not fall into this category which means REST will typically be easier for you to implement.
Just because Facebook created something that does not mean that as a CMS developer, you should blindly adopt the standard for the sake of it. Before you pick a path, I advise you to consider the points made in this article so you can pick which option you think is most appropriate for your needs. GraphQL helps solve problems for intricate relational data models and teams grappling with substantial scalability challenges. Does that sound like your CMS project? Happy Coding 🤘