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
From:

GraphQL Galaxy 2020
Transcription
Hey, 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 help to 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 with sharks. 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. So now let's talk about the jamstack because that's what I get paid to talk about. If you like the jamstack like me, you're probably building sites using gatsby or Next or Hugo or Eleventy. And when you build these static sites, you're likely going to pull data from multiple different data sources, right? One of which could be a CMS. Now there's a lot of great CMSs to pick from. These include Contentful, Sanity, Tattoo CMS. But it turns out wordpress is still really popular. wordpress still powers about 30% of all websites on the web in 2020. And wordpress is a great CMS. I mean, it's got a familiar writing experience. People have been using it for years now, so they're really comfortable with how it works. It's got a wealth of plugins to do really anything you want to do with it, including stuff like advanced custom fields, WooCommerce, free e-commerce, and so on. wordpress also happens to be open source, and that's great because that means there's no limit on... I mean, you can build it anywhere and run it anywhere. You're not tied into a specific platform. And typically with a lot of CMSs, we see that the number of users you can have on a space is typically limited, and that ends up being a bottleneck, especially when it comes to pricing. With wordpress, this isn't the case. So wordpress is still super flexible, and it's a great CMS to use. But if you're building a site in today's day and age, you're probably using a javascript framework. You could be using react, vue, svelte, really anything you like. But when you build your site using one of these frameworks, you're typically going to consume your wordpress CMS instance using its REST api. And the moment REST api is getting to the picture, we're back to seeing those familiar issues, stuff like overfetching, stuff like underfetching. And it turns out that rendering a simple post then becomes a matter of more than one, two, or even five network requests. Let's look at a concrete example of what this looks like. 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. And we have four articles on this home page. Now to render this page, which again, like I said, has posts and authors, you'll 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. Now 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 that's a lot of data over the wire. 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. And 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 dock 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 WP graphql. If you haven't seen WP graphql before, it's a plugin for wordpress. It happens to give you a one-click graphql api right out of the box. 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. And 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 WP graphql installed. So let's take a look at what that gives us. The first thing we see is this really nice graphql IDE button. Let's click on that. And there you go. We see our familiar graphql IDE. And this is great because this is going to help us write our queries. So 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 that it, as we saw before, renders a bunch of cards. Each of these cards are rendered from some articles. And those articles are fetched in this custom react hook, which does a bunch of those api calls, as you can see. And then it transforms them into a shape that our card component requires. And then our card component goes ahead and renders that. Right now, this works just fine. It's running on localhost 8000. And you can see that it makes those requests and renders these cards. Let's go ahead. But yeah, 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. Supposed to be 9, but I see 8 right now. Maybe I'm counting wrong. Oh, there you go. There's the ninth one. So 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, shall we? So 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. But I'm going to delete that. And let's write this graphql query from scratch. So 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, which happens to have a node, 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. So 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. And that has a node with a URI, also has a source URL. So let's use that. We'll also probably need the slug because that'll 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. 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. So let's delete all of that. And now that that's gone, let's go ahead and import use query from urql. I love urql. I think that 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 result from use query and when we call it, I think this 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 urql uses post by default WP graphql prefers get. So 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. So I'm just going to, there you go. 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 goes ahead and calls this query. Let's go ahead and destructure our data and fetching from our result in urql. And finally, why is this complaining? Because I'm still inside the function. 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. Let's take a look at our logs and see if that works and what that does. So we see, interesting. Did that not save? There's an error and it refuses to compile because articles is no longer, there you go, articles doesn't exist. So I'm just going to 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 going to go ahead and I think we need to transform our data a tad because the data format that we have from WP graphql is going to 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 going to return a certain object. 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.featuredimage.node.source URL. Finally author is going to be post.author.node.name. And avatar URL is going to be post. I cannot spell today. Anyhoo, so this is going to be post.author.node.avatar.url. I think this should just work. Let's go ahead and we have no errors. Let's go ahead and take a look at our client. I'm going to hit refresh. And there you go. It just works. We have the entire page rendering. All our cards look good. It has all the data we were looking for. So we just took a javascript like a site built with react. Really, you could use any javascript framework. But we just took some javascript code that called a bunch of these REST APIs and swapped it over to use graphql with WP graphql all within a few minutes. And it was that easy. 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, right? And 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. And WP graphql is a gatsby-sponsored project. It works out of the box with apollo or kill 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. So it's been around for a while. It's been used in production at scale for a while. 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, 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, it should work with any stack, it's just an api. This truly makes wordpress a headless CMS. And yeah, 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. Go ahead and follow him. He's fantastic. Tyler, who also is another coworker of mine, has been building gatsby-sourced wordpress. So if you like gatsby and you'd like to use WP graphql with gatsby site, gatsby-sourced wordpress, it's 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 saying a lot, right? 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. Oh, absolutely. I am not going to tell people that you secretly asked me to introduce you in a very serious way. Yeah, don't tell anyone. Yeah, don't mention it. Absolutely. The secret is between us. Awesome. So did you check out the results from your poll? 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. Turns out 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. So if you're building a site that has about roughly a thousand or maybe even ten thousand 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. 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, you know, 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 you could see is, you know, torches underwater. And I remember seeing a little turtle and it was asleep, you know, under a little sort of like 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 without further ado, let's jump right into your Q&A. We have a question from our attendees on Discord. And the question is, can you explain the concept of data subscriptions? Sure, absolutely. data subscriptions right now, I mean, if 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 real time-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 calling 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, go 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. I think there's also a 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. 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 of 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. That's awesome. That's a great answer. I actually did not know about this. So this is like a TIL moment for me. Definitely going to check that out myself. Also I am going to try to see if we can squeeze in another question before the break for you. How WPGraphQL supports ACS and other popular wordpress plugins? What do you think about that? That's a great question. So wordpress is a nice platform because it's got a wealth of plugins. As I mentioned in my talk, that's one of the reasons that makes it so popular. WPGraphQL supports ACS, which is a super popular wordpress plugin. It's called advanced Custom Fields. There's also WooCommerce and like custom post types and so on. WPGraphQL has plugins of its own that you can also install to add support for these other plugins. I will link to the WPGraphQL plugins page on Discord. So go ahead and take a look at that. But yes, the short answer is it does support most of these really popular wordpress plugins. And by installing these plugins, stuff should just work out of the box. You should be able to query your graphql endpoint. Now enriched with data from these other plugins without any other work. Awesome. That was a great answer. Thank you so much. And also to you folks, keep your eyes peeled for the link that Sid mentioned on Discord. Thank you so much, Sid. That was an amazing talk and even more interesting and informative Q&A session with you. Thank you so much for your time. Thank you. See ya. Bye. Thanks for listening.