So you’re looking into decoupled WordPress. One of the first decisions you’ll need to make is whether you want to use the native REST or WPGraphQL API. Both are good options but there are important differences that I’ll cover here.
Table of Contents
The biggest factor here is probably you and any team members. What tech are you comfortable with? Is this a professional project where speed and quality are important? Is this a personal project where you’re trying to expand your experience and skill set? Answers to these questions will give you a strong indication of what tools you should pick. Keep reading if you want to learn more about the technical differences between Rest and GraphQL
✅GraphQL eliminates the N+1 issue because of the graph. You can get post data, that post’s author data, and anything else all in one query. Gone are the days of fetching the post just to make 3 or more requests for data on the author, tags, categories, etc. This explicitness reduces over fetching of data too.
⛔These benefits come with increased maintenance load. Generally, a GraphQL client will be more complicated, and fetching data requires you to know exactly what you need.
✅It’s easy. You will probably just use
fetch to request data.
⛔This client simplicity and lack of external dependencies mean more N+1 issues and over-fetching of data.
✅GraphQL over HTTP is usually done with a
POST request. This means no HTTP caching by default. The WPGraphQL Smart Cache plugin helps solve this by enabling caching for
POST requests using the Transients API or an object cache (e.g. Redis), if available. The plugin also enables Persisted Queries which allows better support for GraphQL via
GET request and thus leveraging standard HTTP caching. Finally, the smart cache plugin can be integrated with your HTTP cache to purge GET requests out at the CDN very precisely. This isn’t doing a “purge all” every time something changes, it’s purging specific queries that contain the specific data you just edited. This is extremely performant. Outside of WP and your host’s support, there are also 3rd party GraphQL-specific caching options such as Stelate.
⛔Persisted Queries are not the easiest thing. They do require some work and GraphQL client support. Your CDN must also be supported. Currently, WPEngine is the only host or CDN to support this out of the box.
⛔ You might think standard HTTP caching works out of the box, but you’d be wrong. By default, the WP REST API provides no caching headers. This means network and browser caches are left guessing as to if and how they should cache these routes. Your host might be doing something to try and solve this. For example, WPEngine adds
cache-control: max-age=600, must-revalidate to public requests. If you have an auth cookie for the site they disable HTTP caching. In the end, there is no easy way to do precise cache invalidation easily. Your mileage will vary.
✅Luckily there is the WP REST Cache plugin. This provides caching of any GET responses using the Transients API and also intelligently flushes that cache based on the specific content edited. This is not a CDN cache, but it’s still a huge win.
✅WPGraphQL has an active community building plugins to support various best-in-class third-party plugins. SEO, Forms, custom fields, blocks, commerce, etc.
⛔ Few first-party integrations exist but generally decoupled UIs need few plugins.
✅Many plugins have REST API support.
⛔ These implementations and their quality vary widely. More on this in ‘types.
✅WPGraphQL is strictly typed. If you expect a string, you’ll get a string.
⛔ While WordPress supports a declarative schema, not all plugins implement this or even adhere to their own types. It might say it returns a string, but actually gives you an object sometimes. See:
✅Standard HTTP caching works out of the box. Any CDN or server-side HTTP cache such as Varnish that’s on your server, is helping you out. It’ll Just Work out of the box.
✅Making HTTP calls is also super easy with
✅Built into WordPress
✅Supported natively by many plugins
✅ Strongly typed
✅ Eliminates over/under fetching of resources