WordPress has been around for a really long time and is the most popular CMS on the web. Consuming its REST API however to build modern static sites leaves a lot to be desired. In this talk, we’ll live code a site that consumes WordPress over GraphQL and see the power of GraphQL in making mature and familiar services, easy to consume.
Using GraphQL on WordPress
AI Generated Video Summary
WordPress, powering 30% of all websites, faces issues with overfetching and underfetching when using its REST API. WPGraphQL, a plugin for WordPress, solves this problem by using GraphQL, reducing API calls and improving scalability. By installing WPGraphQL and writing queries, developers can easily fetch data and transform it for rendering. WPGraphQL has been used by popular websites like qz.com and apollographql.com, and it recently hit 1.0. Gatsby Source WordPress is a faster version of Gatsby that works well with WPGraphQL, and Gatsby can handle building large sites. WPGraphQL does not currently support data subscriptions, but community contributions are welcome. The new Gatsby-sourced WordPress plugin offers benefits like real-time preview and incremental builds.
1. Introduction to WordPress and GraphQL
Hi, I'm Sid and today I'm going to be talking about building modern websites with WordPress and GraphQL. WordPress is still really popular, powering about 30% of all websites on the web in 2020. It has a familiar writing experience and a wealth of plugins. With WordPress, you're not tied into a specific platform and there are no limits on the number of users or pricing. However, when consuming the WordPress CMS instance using its REST API, familiar issues like overfetching and underfetching arise, resulting in multiple network requests for rendering a simple post.
Hi, I'm Sid and today I'm going to be talking about building modern websites with WordPress and GraphQL. So a little bit about me, I live in Mumbai in India. I work at Gatsby Inc, I help maintain Gatsby open source, I also helped build incremental builds on Gatsby Cloud. Currently, I'm working on Gatsby Functions, which is a serverless implementation built into Gatsby, it's coming soon. I'm also writing a book called web development for everyone. You can check it out at webdevelopmentforeveryone.com.
Besides that more stuff about me but fun stuff now, I like diving, especially in wrecks and jacks. I'm also learning how to fly a plane this year on weekends. And I'm also trying to buy a PS5 if you know where it's in stock, tell me please.
2. Building Modern Websites with WPGraphQL
This is a site that I built up called The Good News Times. It resembles popular news sites and has cards representing articles with images, titles, text, authors, and author images. To render this page, using the REST API requires nine API calls for just four posts, which is slow, data-intensive, and not scalable. To address this, we can move to GraphQL, specifically using the WPGraphQL plugin for WordPress.
This is a site that I built up. This is a mockup. And it's called The Good News Times because we could all use some of that. And this resembles a lot of popular news sites. And as you can see, there's a bunch of cards. Each card is an article. It has an image, it has a title, some text. It also has an author and an author image. Right. And we have four articles on this home page.
Now to render this page, which again, like I said, has posts and authors, you need to make nine API calls to WordPress if you happen to use the REST API. And I've listed all of these API calls and you'll see that there's one to get all the posts themselves, and then there's one for each author and one for each featured image. That sums up to nine API calls for just four posts. And that's a lot. Right. Now, you know, in the past, we've used GraphQL to wrap REST APIs. And when you do that, on the client, that kind of helps simplify your code base. But stuff is still slow because you're still making nine API calls. And it's a lot of data over the wire. Right. And it's also brittle because if you happen to have code that maybe one of those API calls fails in, you're still going to have to sort of handle that for each and every one of them and make sure you gracefully take care of all those error cases. Also, needless to say, this doesn't scale really well. We're looking at a lot of API requests for a single page load. And the moment we talk at scale, this stuff adds up.
So let's try to move this over to GraphQL. That's what this talk is all about. It's about building modern websites on WordPress with GraphQL. So the way we're going to do this is we're going to use WPGraphQL. If you haven't seen WPGraphQL before, it's a plugin for WordPress. It happens to give you a one-click GraphQL API right out of the box.
3. Installing WPGraphQL and Reviewing Code
Just install WPGraphQL and get a GraphQL API. It has plugins for popular WordPress features like WooCommerce and advanced custom fields. We already have WPGraphQL installed, which provides a graphical IDE for query writing. In our code, we have a sample project that renders cards from fetched articles. The cards are rendered fine, but we still have some API call issues.
Just install it. It doesn't need any settings to start with, and you get a GraphQL API. It also happens to have plugins for really popular stuff on WordPress like WooCommerce and advanced custom fields.
I've already gone over and set up a WordPress site, and the WordPress site here, as you can see, is running locally on my machine. It's called Good News Site. I've also gone ahead and installed the plugin. As you can see in our plugins page, which is opening, there you go, you see that we already have WPGraphQL installed.
Let's take a look at what that gives us. The first thing we see is this really nice graphical IDE button. Let's click on that. There you go. We see our familiar graphical IDE. This is great. This is going to help us write our query.
Let's go back to our code and take a look at what we need to do to move it over to GraphQL. We have this sample project here. What this project does is, as we saw before, it renders a bunch of cards. Each of these cards are rendered from some articles. Those articles are fetched in this custom React hook, which does a bunch of those API calls, as you can see. Then it transforms them into a shape that our Card component requires. Then our Card component goes ahead and renders that. Right now, this works just fine. It's running on localhost 8000. You can see that it makes those requests and renders these cards.
Let's go ahead. Before we go ahead, we can still see that there are a bunch of those API calls. You see 1, 2, 3, 4, 5, 6, 7, 8. It's supposed to be 9, but I see 8 right now. Maybe I'm counting wrong. Oh, there you go.
4. Working with GraphQL and Fetching Data
We're going to make the API calls work with GraphQL. We need the title, description, slug, image URL, author name, and avatar URL. Let's write the GraphQL query, starting with posts. For each post, we want the title, content, author, and avatar. We also need the feature image and slug. Running the query fetches all the data.
There's the ninth one. These are all the API calls it's making. That's a lot. We've spoken about that. Let's go and make this work with GraphQL.
The first thing I'm going to do is I'm going to go ahead and take a look at all the data we need. We need a title, description, slug, image URL, the author name, and the avatar URL. Let's go ahead and write our GraphQL query. To do that, you'll see that I won't read it now because I practiced this a while ago. I'm going to delete that. Let's write this GraphQL query from scratch.
The first thing we're going to need is posts. We want all of them. We only have four posts right now. Otherwise, we could add a filter, but let's ignore that for now. For each post, we want the title, we want the content, we want the author. It happens to have a note which will have the author's name. We also want their avatar, which I think has a node as well. Oh, it doesn't. It just has a URL. That's great. Now we have everything about the post and the author, but we also need the feature image. I think that's called ... There you go. It's called featured image. How convenient. That has a node with a URI, also has a source URL, so let's use that. We also probably need the slug, because that will help us have some kind of key for each post. So let's go ahead and get that slug as well. I'm going to run this query, and as you see, I get all the data, and that's great.
5. Setting up GraphQL and Writing Queries
Let's set up GraphQL for our project by importing useQuery from urql. We'll create a client with a URL and wrap our layout components. Then we'll write a query and get a result using useQuery. Finally, we'll destructure the data and fetching from the result in urql.
It just works. So let's keep this query here. Let's go back, set up some GraphQL for our project. So I think what we want to do in this case is, let's get rid of all of this. I love deleting code, right? So let's delete all of that. And now that that's gone, let's go ahead and import, let's go ahead and import use query from urql. I love urql. I think Patty is talking about urql today, or maybe yesterday, but anyway, let's write a query.
So what we're going to do is we're going to get a result from use query, and then we call it. I think this takes, there you go, takes an object which has a query, and that can be a string, and I'm going to go ahead and copy this, paste it right here. And before this just works we're going to want to wrap our layout components. Let's go ahead and do that. Let's import, I think it's called create client and provider from urql and let's go ahead and create a client. So I think what that needs is a URL, there you go, and our URL in this case is going to be our site slash GraphQL, like we're used to seeing. So let's go ahead and set that. And we're also going to set prefer get method to true. I think Oakley uses post by default WP GraphQL prefers get, so let's just, let's stick to get for now. So we have a client, we're going to go ahead and wrap, I just realized that this probably should have been index, so let's go ahead and move this over to our index and then wrap the layout instead of putting it in layout, right? So I'm just going to, there you go. That should, that should be fine. And now let's wrap our provider in here. We're going to set a value to the client. And I think that's all we should need. So we have our provider in place, we have our article component that, you know, goes ahead and calls this query. Let's go ahead and destructure our data and fetching from our result in orcl. And finally, why is this complaining? Because I'm still inside function. There you go. So let's go ahead and put that there. Let's log data. Let's also go ahead and say that if fetching is true, we probably want to return null, right? Let's take a look at our logs and see if that works and what that does. So we see...
6. Transforming Data and Rendering
Interesting. Did that not save? Hmm. Right. There's an error and it refuses to compile because articles is no longer... There you go. Articles doesn't exist. I'm just gonna comment this out and hit refresh. And we see that we have data now besides all the other errors. We do have data with posts and notes.
So we have our data. Let's now go ahead and write everything we need to make it render. So I'm gonna go ahead and... I think we need to transform our data a tad because the data format that we have from WP GraphQL is gonna be slightly different than what we had from the REST API. So let's go ahead and map these, and let's say each of them is a post, and we're gonna return a certain object, right? And we know that we want stuff for our cards. Let's go ahead and copy those keys in here. Let's say this is name, and this is avatar URL. We should be able to set these fairly quickly. Title is post or title, as we know, because we wrote the query. Description is going to be post.content. Slug can just be post.slug. Image URL, I reckon, is post.featured image.node.source URL. Finally, author is going to be post.author.node.name. And avatar URL is going to be post, well, I cannot spell today. Anyhow, so this is going to be post.author.node.avatar.url, right? I think this should just work, so let's go ahead and...
7. Comparisons and Conclusion
Our REST API needed about nine requests to render the page, while WP GraphQL only needed one network request. WP GraphQL is a great way to get GraphQL working in your WordPress project. It works out of the box with Apollo or KIL and has plugins for common WordPress features. It has been used in production by qz.com, apollographql.com, Denver Post, and more. WP GraphQL recently hit 1.0, marking its first stable release. This makes WordPress a headless CMS.
So yeah, let's talk about some quick comparisons. Our REST API needed about nine requests to render that one page. WP GraphQL with GraphQL, we needed to make one network request in total. The JSON API eventually took about roughly a second and a little more than a second, WP GraphQL took less than a third of that. And that's great because if you look at the amount of data as well, and this was all running locally, but of course, these numbers can grow dramatically when you're running this, like when this stuff happens over the network. For the JSON API, it downloaded 13.7 KB, whereas for our GraphQL request, it downloaded 1.6 KB.
I ran some load tests, I was able to hit the REST API for about roughly hundreds of requests in a second, whereas the GraphQL API, I was able to hit about a thousand per second. That's roughly a 10X. Well, not roughly, that is a 10X difference.
So yeah, that's what WP GraphQL is. It's a great way to get GraphQL working in your WordPress project. WP GraphQL is a Gatsby-sponsored project. It works out of the box with Apollo or KIL. It's really any stack you'd like. It has plugins for all the common WordPress stuff. It's also used in production by qz.com and apollographql.com and Denver Post and many more. It's been around for a while, it's been used in production at stakes. It also hit 1.0 recently and that's a big deal because this marks its first stable release. My slides have a link to the release notes for the 1.0 release as well as the blog post that Jason wrote. And with that, that's WP GraphQL. It works out of the box, like I said, with stuff that uses runtime GraphQL. out of the box with stuff that uses runtime GraphQL. Like Apollo or Opel or if you'd like to use GraphQL at build time like Gatsby does, that also works out of the box with WP GraphQL. And really, like I said before, should work with any stack. It's just an API. This truly makes WordPress a headless CMS. And that's my talk. I'd like to thank Jason. Who's built WP GraphQL over the years, and this is a funny picture of him posing as the Tiger King. There's also his Twitter on this slide.
8. Gatsby Source WordPress and Poll Results
Tyler has been building Gatsby source WordPress, a new version that works right out of the box and is a lot faster than previous versions. Follow him on Twitter, he's a great guy. WP GraphQL is fantastic and I hope it makes you as happy as Peppa Pig makes my niece. The poll results were surprising, as people often think building large sites with static site generators like Gatsby is problematic. We're investing a lot of time in making Gatsby work better at scale, and we have many customers building thousands of sites on Gatsby Cloud.
Go ahead and follow him. He's fantastic. Tyler, who also is another co-worker of mine has been building Gatsby source WordPress. So if you like Gatsby and you'd like to use WP GraphQL with Gatsby site, then this is the one for you to build.
Gatsby source WordPress, its new version that Tyler has been building, works right out of the box. It's a lot faster than the previous versions that use the REST API. You can follow him on Twitter. He also happens to be the nicest Canadian guy, you know. And that's a lot. That's saying a lot because Canadian people are nice.
And yeah, I hope WP GraphQL makes you as happy as Peppa Pig makes my niece. Thank you. Hello, how are you? Hey, I'm good. Thank you for the kind intro. This was fun. Absolutely. I am not going to tell people that you secretly asked me to introduce you in a very, I think, serious way. Yeah. Yeah. Don't tell anyone. Yeah. Don't mention it. Absolutely. Yeah. The secret is between us.
Awesome. So did you check out the results from your poll or were they... Were they interesting? What were you expecting? Yeah, they were also surprising because, well, in a way, I guess they were surprising and also kind of not very surprising because it's a common misconception that people have with the fact that they think that building really large sites with static site generators like Gatsby is problematic. We've invested a lot of time and we still are into making Gatsby work better at scale. And we actually have a lot of customers on Gatsby Cloud currently building sites that are in the thousands.
Building Large Sites and Q&A on Data Subscriptions
If you're building a site with thousands or even 10,000 pages, Gatsby can handle it. I had a favorite dive in the Maldives where I woke up a sleeping turtle. Now, let's move on to the Q&A. The first question is about data subscriptions.
So if you're building a site that has about roughly, you know, thousand or maybe even 10,000 pages, that's fine. You should expect that to, I'm sorry, you should expect that to build within 30 to 45 minutes even. So yeah, you can build much larger sites than 100 pages with stuff like Gatsby.
That's awesome. That's super interesting to find out.
So before we start with your Q&A, I had a super interesting question for you. You also mentioned, actually I mentioned in your intro that you love to do scuba diving as a sport. So like, what was your favorite time, your best time scuba diving? Did you find anything interesting below the waters?
That's a really great question. I didn't expect that. Thank you for asking that. I love diving, yes, and there have been a lot of dives that I'd consider amongst my favorites. I think one of my favorite dives was one in Maldives last year. It was a night dive, so it was post 7 p.m. It was really dark. The only stuff we could see is torches underwater. And I remember seeing a little turtle and it was asleep, you know, under some coral. And I got really excited because I wanted to tell everyone else about the turtle, because it just looked so beautiful, that I started flashing my light and I woke it up. It got up, looked at me and then swam away. So that was sad. So I feel terrible about that. But it was beautiful. I love turtles. So it's like the story about the sleeping turtle, except you woke the turtle up and you're the cruel prince instead of the charming prince. Yeah. I'm sorry.
All right. So with no further ado, let's jump right into your Q&A. We have a question from our attendees on Discord. The question is, can you explain the concept of data subscriptions?
Data Subscriptions and Community Contributions
Data subscriptions are not currently supported by WPGraphQL, but there are plans to work on it. You can contribute to WPGraphQL on GitHub if you have PHP skills. That's a great opportunity for community contributions.
Data subscriptions right now. I mean, if you're talking about the concept, the concept is actually fairly simple. Typically, over GraphQL, you can, you know, send requests for some data. And you'll just receive back one response, which you can also do in, you know, in some frameworks right now is that you can, instead of asking for one request, open a socket connection and have responses getting streamed in as they get updated. And that works really well for sort of realtime-esque apps. In context of my talk, WPGraphQL currently does not support data subscriptions. So, I mean, the only way to really fetch data over again is by polling things. But it's interesting because I have heard Jason mention that it's something that they'd like to work on. And yeah, go up on the issue. Talk to Jason and the other folks over at WPGraphQL on GitHub and tell them that you'd like to see subscriptions coming in sooner. That's awesome. That's also really great opportunity here for community contributions I see. Absolutely. I mean, if you can write PHP better than me, I can't write a lot of PHP. Feel free to take a look at WPGraphQL and contribute. We'd love that. Awesome.
Benefits of Gatsby-sourced WordPress Plugin
The new Gatsby-sourced WordPress plugin provides benefits like real-time preview and incremental builds, which are not supported on Gatsby-sourced GraphQL. It offers live preview out of the box and is recommended for those who have used Gatsby-sourced GraphQL in the past. If you encounter any issues, feel free to open an issue on GitHub for assistance.
So another question for you is what are the benefits of using the new Gatsby-sourced WordPress plugin over Gatsby-sourced GraphQL? That's a great question. So if you're using, if you happen to be using Gatsby and you're using WPGraphQL on WordPress to fetch data, up until very recently, the only way to consume that data was by using Gatsby-sourced GraphQL. And Gatsby-sourced GraphQL, in case you're not familiar, is a Gatsby plugin to fetch data from any arbitrary GraphQL endpoint. And it works great, but there are certain optimizations that we've made in the new Gatsby-sourced WordPress experimental plugin, which enables stuff like real-time preview and incremental builds on Gatsby Cloud, all of which are not supported on Gatsby-sourced GraphQL. So yeah, the biggest benefit of using Gatsby-sourced WordPress, the new version, with WPGraphQL is that you get live preview out of the box and you also get incremental builds. So in case you've used Gatsby-sourced GraphQL in the past, try to move your site over to Gatsby-sourced WordPress, and if that's hard or if you're encountering issues, feel free to open an issue on GitHub and I'd be happy to help. But yeah, that's the core benefit, that's what I'd recommend.