π ββοΈ Why GraphQL should not be in WordPress core
Update 01/05/2024: Check-out the Gato GraphQL vs WP REST API comparison.
Yep, you read that title correctly. Even though I am myself the creator of a GraphQL server for WordPress, I've changed my mind concerning if WordPress should ship with GraphQL or not.
Until not long ago, I believed that GraphQL should be in WordPress core. The logic was that contributors were spending time and effort on implementing functionality for the WP REST API (batch operations) which is native to GraphQL.
However, I have lately learnt some new information which made me think again, and now I believe WordPress should not ship with GraphQL, because of the added risks.
These are my reasons.
1. It doesn't satisfy the 80/20 rule
Historically, a certain functionality is added to WordPress core only if it satisfies the 80/20 rule, meaning that 80% or more of the users will use it.
Would that be the case with GraphQL? I think the answer is "no", based on the precedent from the introduction of the WP REST API to WordPress 4.7.
In his talk WordPress as Data, 5 Years In, K. Adam White (main lead of the initial development and release of the WP REST API) described that the contributors expected the REST API to be widely used once it was released with core. But that didn't happen: developers kept creating WordPress sites the same way as before, paying little attention to "headless" or the REST API.
Fortunes changed only later, with the introduction of the Gutenberg editor in WordPress 5.0, which was based on the REST API. Could Gutenberg then justify the addition of GraphQL to WordPress core?
2. Headless is already satisfied via the REST API
The WordPress editor can be enhanced with a native GraphQL server, allowing block developers to use GraphQL (in addition to the existing REST API) to fetch data for their blocks. In addition, themes and plugins could make use of GraphQL to power their own internal functionality. These are strong reasons to add GraphQL to WordPress core.
However, WordPress already has the REST API, and whatever you can do with GraphQL can also be done with REST. Introducing GraphQL in addition to REST is akin to buying a BMW when you're already driving a Toyota. You will reach your destination faster, and the driving experience will be more appealing. But both cars will take you to where you want to go.
Because GraphQL will not provide a previously-unavailable functionality, then its inclusion in core is not fully justified. GraphQL would certainly enhance the experience of interacting with the API, but this could be perfectly considered plugin-land.
webonyx/graphql-php
3. WordPress themes and plugins can use
Public plugins cannot require a website to install either WPGraphQL or Gato GraphQL in order to use the plugin, since that will diminish their potential reach. As such, public plugins cannot rely on GraphQL, and that's a real pity.
I thought hard about this issue, and I came up with a potential solution: the GraphQL API Private, a self-contained GraphQL engine that plugins can embed for their own use, distributed as a Composer package. (I haven't started working on this project yet.)
But then, a few weeks ago, a GraphQL-powered WordPress plugin was released. I wondered how the author did it: would it be using WPGraphQL or Gato GraphQL under the hood? So I checked its source code and, as it turns out, it's directly using webonyx/graphql-php
!
This is an interesting solution, which demonstrates that, with a bit of effort, developers currently do have access to GraphQL for their themes and plugins.
This plugin uses GraphQL to fetch its own data entities, and not those of WordPress (posts, users, comments, etc). Then, it doesn't need to recreate the GraphQL schema containing the WordPress data model, as done by WPGraphQL and Gato GraphQL (and eventually the GraphQL API Private). As such, relying on webonyx/graphql-php
makes sense.
4. GraphQL presents additional risks
All three issues above suggest that GraphQL would enhance WordPress, even though it's not extremely compelling. In this light, we could still add GraphQL to WordPress core, and either benefit from it or nothing happens.
But this 4th issue suggests that, if GraphQL will not add much value to WordPress, then it should not be added, because of its added risks.
GraphQL is susceptible to the following attack vectors (among others):
- The single endpoint provides access to all information from the website, so we could have private data unintentionally exposed.
- The queries can be very complex and may overwhelm the web and database servers.
- The same mutation can be executed multiple times in a single query, and multiple queries can be executed together in a single request, allowing attackers to attempt gaining access to the back-end by providing many combinations of user/passwords.
These attacks can be really damaging. In his presentation Damn GraphQL - Defending and Attacking APIs, the cybersecurity researcher Dolev Farhi managed to bring down a WordPress site in less than 30 seconds, by attacking the WPGraphQL endpoint with a batch of complex queries.
The WPGraphQL team fixed the issue immediately. But how can we be sure that no other exploit can take place? (I mean not only WPGraphQL, but Gato GraphQL too.)
These attacks can happen with GraphQL, and not with REST, because GraphQL is more powerful than REST. While in REST the query is defined in advance and stored in the server, in GraphQL it is provided on runtime by the client (unless using persisted queries).
If website admins are sloppy configuring who can access the endpoint, or which data gets exposed, then bad things can happen. And due to the popularity of WordPress, which is used by millions of people who are not tech-savvy, then bad things will most likely happen.
Wrapping up
Just to be sure: I am not advocating to not use GraphQL in WordPress (of course I am not!), but to use GraphQL responsibly. GraphQL is powerful, which means it is dangerous. When using GraphQL, we need to be sure we know what we are doing.
Shipping GraphQL in WordPress core would put it in the hands a lot of people, many of which will not be aware of its risks, and not take appropriate measures. It's a recipe for potential disaster. And as such, it is now my opinion, it should be avoided.