What Is GraphQL?
GraphQL is a query language for your API(s). It describes the data in your API(s) and gives clients the power to request exactly and only the data they need. It empowers and speeds up development.
To learn more, start here: https://graphql.org/
The name of the language is derived from the concept that application data can be represented as a graph with nodes and edges. The language enables the client to traverse the nodes and edges and return only the data that was request.
This article provides more details:
https://www.apollographql.com/blog/graphql/basics/the-concepts-of-graphql/
This article draws a simple comparison between using the WordPress REST API and GraphQL (via the WP GraphQL plugin) and outline some advantages of the latter.
The WP GraphQL plugin comes with its own IDE – and integrated tool for exploring the schema, and building queries and mutations – https://svilenstoicheff.com/wp-admin/admin.php?page=graphiql-ide
Example Task
Let’s solve a simple problem: Request all WordPress pages and their authors.
GraphQL
The query will look like this:
{ pages { nodes { title author { node { name } } } } }
In a large WordPress application, the response may be quite large, but we won’t worry about that now.
The response will look like this:
{ "data": { "pages": { "nodes": [ { "title": "GraphQL Is Better than WP REST API", "author": { "node": { "name": "svilenstoicheff" } } }, { "title": "JavaScript: Select ES6 and Later Features", "author": { "node": { "name": "svilenstoicheff" } } }, { "title": "Contact", "author": { "node": { "name": "svilenstoicheff" } } }, { "title": "About", "author": { "node": { "name": "svilenstoicheff" } } }, { "title": "Create your website with blocks", "author": { "node": { "name": "svilenstoicheff" } } }, { "title": "Sample Page", "author": { "node": { "name": "svilenstoicheff" } } } ] } }, "extensions": { "debug": [ { "type": "DEBUG_LOGS_INACTIVE", "message": "GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled." } ] } }
If I were to save the above JSON to an object call myData, I can parse it and display article headlines and authors with this one-liner:
myData.data.pages.nodes.forEach(item => console.log(`${item.title}, by ${item.author.node.name}`))
The above GraphQL query can be executed as a GET request as well:
https://svilenstoicheff.com/graphql?query={pages{nodes{title%20author{node{name}}}}}
We can then write a small JS program to retrieve the response and format it in the console, or on the page, like this:
const endpoint = 'https://svilenstoicheff.com/graphql?query={pages{nodes{title author{node{name}}}}}'; const options = { method: 'GET', headers: { 'Content-Type': 'application/json' }, mode: 'no-cors' }; fetch(endpoint, options) .then(response => response.json()) .then(data => data.data.pages.nodes.forEach(item => console.log(`${item.title}, by ${item.author.node.name}`))) .catch(error => console.error(error));
WP REST API
The endpoint for pages is this:
https://svilenstoicheff.com/wp-json/wp/v2/pages
The response for that is pretty large, but we can filter it by providing additional URL parameters and specify the fields we need. Here is an example:
https://svilenstoicheff.com/wp-json/wp/v2/pages?_fields[]=title&_fields[]=author
The response will look like this:
[ { "title": { "rendered": "GraphQL Is Better than WP REST API" }, "author": 1 }, { "title": { "rendered": "JavaScript: Select ES6 and Later Features" }, "author": 1 } ]
We can see that the /pages endpoint doesn’t contain the author’s name or alias, but only a numeric ID. In order for us to retrieve the name, we will need to make a second call to the /users endpoint, and get the name for the respective ID. Like this:
https://svilenstoicheff.com/wp-json/wp/v2/users/1?_fields[]=name
If we only have a couple of IDs to look up, that’s fine, but what if they are 200? Making API calls in a loop will make that a burdensome or even impossible task. We can make a single call to the /users endpoint requesting only the ID and name fields for authors:
https://svilenstoicheff.com/wp-json/wp/v2/users/?_fields[]=name&_fields[]=id
But then we’ll need to write another program to look up the authors by name and display then as bylines for the respective articles.
Alternatively, we can create a new custom endpoint to return only the data we are requesting, but that’s a lot more work, too.