 Oh, thanks. Yeah, so this is a fairly technical talk. So since I have to hold this mic, it might get a little weird at some point, so apologize. But yeah, so talking about WP GraphQL, a new way to interact with WordPress data. If you don't have the Wi-Fi info and want to log on, I put the Wi-Fi info up here. I'll leave that up for just a sec for anybody who wants to get on. I'll also have a link to the slides if anybody wants to follow along. All right, so first off, who am I? Currently a senior WordPress engineer, Digital First Media in Denver, Colorado. The large publishing company. We have like 100 plus newspapers across the country. Use WordPress pretty heavily there. Been a WordPress developer full time for about nine years. Doing GraphQL development for about a year and a half. Denver native and creator and maintainer of a WordPress plugin called WP GraphQL, which I'm talking about today. So previous talks I've given, as she mentioned, I've talked at several WordCamps already, and I've done talks about why to use GraphQL, so you can look that up. I'm not gonna give you the pitch on why to use it. I'm gonna jump straight into how to use it this time. So if you're curious on reasoning why it might be a good fit, I got lots of material out there. Just go to graphql.org. That's not my side. That's the actual GraphQL site, but they'll sell you on it too, so. I'm gonna jump straight into how to use it, and I think that'll probably sell you on why to use it as well. So my agenda for today, I'm gonna talk about what is GraphQL. We're gonna look at what WordPress looks like as an application data graph. We're gonna look at using the WordPress, or the WP GraphQL plugin, and then how to extend it for your needs. And then we'll look at a few examples of WP GraphQL in the wild. And it is a very technical talk, so enjoy. All right, so first off, what is GraphQL? GraphQL, it's an open source spec for a query language that Facebook open sourced They built a query language that they use internally, but then they open sourced a spec that can be implemented in any technology. Just like how JSON is a spec that you can use in any language, GraphQL is a spec that can be used in any language. So GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time and enables powerful development tools. It's probably the most text I have on a single slide, so bear with me on it. So like I said, GraphQL is an open source spec by Facebook, so it's been implemented in PHP, Ruby, Python, Java, JavaScript, Scala, like any language you can think of has a GraphQL implementation pretty much at this point. So I'm using, for my plugin, I'm using the PHP version to bring that to WordPress. One thing I wanna clarify though, GraphQL, some people think, oh, since Facebook open sourced it must have to do with their graph search that they had on, so you could search Facebook data. Same name, different thing, that's a completely different thing, has nothing to do with graph search. There's also database technologies like Neo4j and some others that are called graph databases, nothing to do with those. You can use GraphQL with those databases, but they're not the same. So graph in this in GraphQL means application data graph and QL means query language. So any application data graph you can query with GraphQL. Yeah, so GraphQL, the query language for your application data graph. So this is kind of the hello world of what a GraphQL query looks like. You send a request that looks essentially like JSON keys without the values and the response you get is actual JSON with keys and values. So you ask for what you specify what you want and you get back what you asked for. WordPress as an application data graph looks something like this, at the heart of WordPress we have posts or pages or whatever content we might have. Those posts have properties, let's say a post has a title and that might be hello world. Posts might also be connected to other things like categories or images. And those categories also have properties like names. And those categories have connections to other posts and those posts have titles. And those posts might have other categories and those categories might have an image and the category has name. So that's what an application data graph looks like in a WordPress perspective. We have all this data that has these connections and GraphQL is gonna let us pluck that data out of the graph. So yeah, GraphQL lets us pick trees out of the application data graph. So we could send a GraphQL request to WordPress something like this. We could say, hey, I want a specific post and on that post I want a title, I want a link and I want the categories and on each category node I want the name. We'll get a response like this, that's just JSON with exactly what I asked for. I asked for a post, I got its title, its link, its categories and on each category I got its name. So if we look at application data graph with this request in mind, it would look something like this. So we have the same graph of data but I only asked for one post and its categories. So I just got its post and its categories back. The rest of this data still exists in my application but I didn't ask for it so I didn't get it. So that brings us to using it, actually using it with WordPress. So WP GraphQL is a free open source WordPress plugin that provides an extendable GraphQL schema and API for any WordPress site. So I'm the creator maintainer of it, it's on GitHub, you can go download it, start playing with it, it's technically considered beta still but it's been used in production on a lot of sites including some big sites like DenverPost.com, TwinCities.com, SiliconValley.com, there's a lot of sites using it right now, Quartz.com or QZ.com. So it's technically beta but feel free to use it. Oh yeah, we do have stickers if you're interested. So using the GraphQL plugin, so this is kind of what WordPress looks like today. At the bottom we have a persistence layer, that's MySQL, then we have a business logic layer that handles things like roles and capabilities for users and registration of custom post types and taxonomies and whatnot, if you have a membership site or whatever it is, you have this business logic layer, then you have authorization, that checks to identify, that's also kind of part of that, so it checks who your identity is, what capabilities you have to access data, whatnot. And then at the top of that we have now the REST API, which is what, two years now or something in core, then we have XMLRPC, and these are different ways to interact with WordPress, right? So you can send a request to WordPress, hit a REST endpoint, get JSON data back, use XMLRPC to get data back. So GraphQL sits in this layer, it sits atop these other layers, so you send a GraphQL request to WordPress, it still respects authorization, business logic, and then gets the data out of my SQL. So yeah, WordPress, like I mentioned, at the heart of WordPress we have posts, of course we have users and comments and pages and terms and media, and these all have random connections, or not random, but they all have connections with each other, so WPGraphQL takes that and makes it GraphQL friendly. So let's take a look at how you can start using this plugin, so adding the plugin to WordPress. Right now it's not on the wordpress.org plugin repository, it might be one day, for now it's on GitHub, so you can visit GitHub, download it, clone it, of course start the repo, tweet about how awesome it is to use GraphQL with WordPress of course, then of course clone or download the plugin, then install and activate, right? So if you're on your plugin activation screen, you should see WPGraphQL, I have another plugin called WPGraphQL, which we'll see in a second. I'm gonna show you what it looks like to activate both of these. If you activate both of these, WPGraphQL will give you this menu item here, which gives you this tool called GraphQL inside your dashboard, so. And we'll be looking at using GraphQL to explore a GraphQL API quite a bit in this talk. So I'm gonna jump straight and show you things working. So I put up this site, please don't hit this so much, that it's gonna take the server down. But put this up last night, playground.wpgraphql.com. So this is a React app that just kinda walks through various queries to help you get a feel of how to use GraphQL. So I'll navigate through and show you how things work. So first thing, we'll just take a look at what a kinda hello world type query looks like. So we're just gonna ask the site for some basic info. So we're just gonna ask for the site title, the URL and the language, which is all stored in the options when you configure WordPress site. So this request, I just say, hey, give me some general settings, I want the title, the URL and the language of the site. When I click this play button, it just executes that request and I get my response. Maybe, can we move the video to the bottom corner? Yeah, cool, thanks. So yeah, so it's as easy as that. You send a request, you get the data back. So wpgraphql, though, when you activate it, it builds the schema for you. So, and you can explore the schema in this documentation explorer. So at the root, you have all these types defined in these fields that you can query against. So in my case, like I have a custom post type book, so you'll see I can ask for a book or I can ask for multiple books. I can ask for comments or settings or media items or pages. So any custom post type I have, if I register to have support for GraphQL, it's gonna show up in my schema. And if it's in my schema, I can then go query for it. So that's kind of what a hello world query looks like. I can also search my schema. So if I wanna find posts, I can see what's available in my schema to query for posts. I can find what arguments it has and whatnot. So I'll walk you through some more examples and we'll learn more about the GraphQL query language and how to use it. So next example would be like querying for a list of posts, a very common thing in WordPress, right? To build, let's say, like a blog index page. So normally in WordPress, you'd write something like a WP query to get this data. Behind the scenes, GraphQL is still using WP query and WP comment query and WP tax query. But this is just an abstraction layer that does a lot of the heavy lifting for you. So you just describe what you want and you get that back. So I can execute a query like this. I can say, hey, WordPress, I want some posts. On those posts, I want edges and node, which I'll explain in just a second. And then on each node, each post, I want the ID, title, date, and excerpt. And I can send this over and in response, I'm gonna get a list of posts with the ID, the title, the date, the excerpt. And I can change these fields. Like if I just, for my sake, just wanted the ID and the title, oh, of course. If I just wanted the ID and the title, I can just get the ID and the title. Edges and node, I'll take a side real quick on that. So in GraphQL, if you remember the application data graph, what WordPress looks like, or what an application data graph looks like, you have these nodes. So in our case, we have posts and we have categories or terms. We have images or media items. These would all be considered nodes in the graph. And then the edges would be this kind of space between this contextual space that's not a property of either node. So a classic example would be like a social network, right? I'm a user, you're a user, we're friends. There's a property called friends since. Like we've been friends since 2012 or whatever. It's not a property of me as a user and it's not a property of you as a user. It's just a property of that edge between us, that space between us. So that's where the concept of edge comes. It allows for this space between to exist. WordPress doesn't have a good storage mechanism for that yet. But something like, if you can think with me, like a term relationship meta would be something like that. So a post is in a certain term, like post is categorized as crime and maybe you added, date added to crime, right? That would be like this edge data that only exists in the context of that post with that category. So that's the concept of edges and node. It also provides uses for pagination which I'll get to in a later example. And yeah, we'll look at that a little bit more. So you can also ask for a single entity. So I can ask for a single post with an ID. This ID, you might not recognize what that looks like, right? Because WordPress normally has integers as IDs. So, and this still has the concept of the normal WordPress database integer ID. But this ID that GraphQL uses is a global ID. So it's a base 64 encoded ID of the type with the ID because WordPress doesn't have global IDs. You can have a category with ID one, you can have a post with the ID one, you can have a user with the ID one. So this globalizes IDs. So now I can use this ID, send it back to GraphQL and it has enough info to know if it's a user or a post or a category or a term. So I can then use that to query an individual entity for an individual node. I can use that same ID, pass it back to, I can pass that back to GraphQL. I can say, hey, I have this ID for a node. I don't know exactly what it is. I'm gonna give you the ID. If it turns out when you execute that it's a post, give me the ID and the title back. If it's not a post, I don't want anything. So if I put like an invalid ID, I'm not a, oh, well, screw some up there. Yeah, so, what's that? Yeah, so in this case, I'm still gonna get a response with the one part of the request, the initial post that I asked for. I still get that in my response. Just my second node, it's not a valid ID. I'm not gonna get anything back, but I do get a message back telling you why, right? So then let's, again, posts and pages very similar. I can also ask for a list of pages. So same thing, I'm just gonna send this request for a list of pages. If I wanted one page, I could take the ID and ask for that as well. Yeah, and I'll show some examples to some degree. I'll show an example of that. So yeah, and then with terms, we're gonna look at this really deeply nested example, right? It's like a hierarchical taxonomy. If I wanted to get categories in those categories, children in those categories, children in those categories, children, right, I can send a request like this. I asked, well, of course, live demos, huh? There we go. So I can send this request and say, hey, I want categories and I want their children, I want their children's children and their children's children and I'll get a response that matches that. So anytime I have, I don't think I have any hierarchical, I don't think I have hierarchical relationships in this, so that's probably not the best example for this environment. But yeah, so you can ask for what you want and you're gonna get that back. So then users, again, I can ask for users. Very, very similar concept, right? I just say, give me some users, give me their node data, and I'm gonna get that data back. Also works with plugins, so I can get info on the plugins I have active. Works for themes, so I can see what themes are active on that environment. If they add a gap to fill it, they'll have to write some code to make it work. Yeah, not by default. But if somebody's interested, talk to me, I'll help you figure out how to bridge that gap. But general settings, if you're using the Register Setting API, WP GraphQL knows about that as well. It respects authorization, authentication, callbacks too, so if you try to query for something that's private, you're gonna have to be authenticated to get it. So this is an example, like in WordPress we have several settings pages, right? We have general settings, discussion settings, reading settings, writing settings. I can ask for data from multiple settings in one request and get that back. Like something pretty core to building a decoupled app. I need the site name, right? I need the site URL, things like that. I need the site language so I can, I know if I need a translator, whatnot. So I can do all these things. But if I try to ask for something that's private, like the email address, by default that's treated as a private field. So you have to be authenticated to get that. So if I ask for something private, I'm still gonna get the public data in my response so I can do something with it. I'm gonna get a null value for the email because I don't have access to it. And I'm gonna get a helpful message saying, hey, sorry, you don't have permission to view that. And I get a path to where in my query this message relates so I can render that, let's say, in a DOM if I'm building a React app or a View app or something like that. So I can ask for all this data in one spot in essentially plain English. Like this is hardly code. And the cool thing about this, since it's just a string, I can take this string, I can use it in any language that knows how to make an HTTP request. So I can use it in JavaScript. Let's say I'm building a React app or a View app or Ember or Angular. I can use that if my language can make an HTTP request to WordPress, I can get this data now. So you can use this exact same thing in PHP. You can use it in Ruby or whatever to interact with WordPress. So you don't have to be inside the WordPress context now to get rich data from WordPress. So that's kind of like the intro to the language. I'm gonna take you a little bit deeper into it now because a lot of that stuff you could just look up and get familiar with pretty quick. I wanna take you into some nuance of the actual language now and we'll look at some more advanced examples. So there's something called arguments on GraphQL fields. So previously we were just looking at getting a list of posts and by default, I was getting 10 back. But what if I wanted something other than 10? I can pass this argument first five and I'll get five back on this Wi-Fi maybe. Bear with me. Live debugging. Might have to switch and do this local. Excuse me, I'll switch and do this local. I'm not getting connection anymore. Back to business. So I'm running this locally now. I don't know what's going on. Yeah, so back to that though. I can send a request and specify arguments so I can say, hey, give me five posts or maybe one post and I'm gonna get just that one back. And then as you can see here too, I can get nested data, right? So posts don't just have their individual properties like an ID and a title, but they have connections to other properties like tags or categories or authors. And I can get that data too. Or something like, even in PHP, I'm gonna have to write a WP query and then I'm gonna have to write a WP tax query to use a function like getTerms or something like that. Then I'm gonna have to write a WP user query or instantiate a user object or something like that. So I'm gonna have to write all this code and then figure out a way to connect it all. And then even in like a modern JavaScript using the REST API, something like Gutenberg for example, if I wanted all this data, I'm gonna have to make separate endpoint requests and then figure out on my end how to tie this all together. So WP GraphQL does that heavy lifting for you on the back end. You just say, hey, here's what I want. Here's the shape I want it in. Here's the fields I want from it. It does the heavy lifting, it gets it back to you and then you can be on your way. You don't have to figure out how to glue it all together. And I actually have, we'll look in a second, I have some examples of actually taking this data and putting it into React Components just to see how easy it is. So again, I can also ask for multiple resources at the root of a single request. So here at the top of my request, I'm asking for posts and then separately, but in the same request, I'm asking for users. So in a single HTTP request, I can ask for multiple resources. In typical, like REST for example, or XMLRPC or something like that, I'm gonna have to make a separate request for posts and separate requests for users. Here I can make one HTTP request, I can get a list of posts and a list of users and I can have arguments at different levels too. I can get one user and one post if I wanted. Whatever my use case is, I have this flexibility now to easily declare what I want and get back what I asked for. So another nuance of the GraphQL query language is this thing called fragments. So I can actually define pieces of my query in something called a fragment. So I can say, hey, if the type that's coming back to me as a post, these are the fields that I want. And in this case, if the type coming back to me as an author, I want these fields. So I can define these fragments and then reuse them throughout my application. So if I have multiple components that will render this post data, I can define this fragment in one spot and use it throughout my application in different queries. So when I execute this, it's gonna give me the data that I asked for here. So the ID, the title, the date, the author, and then it's gonna use the author fragment to get that. So when you're building component-based applications React or Viewer, what have you, you can now couple your data requirements with your component. So there's a common pattern of coupling your styles now with your component in React especially, like style components or CSS and JS in general. So now you can actually couple your data dependencies also. So you have one place to go. You can manage your data, you can manage your styles, you can manage your markup right in one spot. And then all you have to do is tell the top level query, these are the fragments to use. So now if you, let's say you built a component that, oh, hey, we need the email address on this user now, that email or the author component, you would just update the fragment right there in that component and then you'll have it, right? You don't have to go chase your application like, wait, where do we fetch the data and then how do we get that data and transform it to our view? Like it's right there, it's in one spot. So another awesome thing with the GraphQL query language, there's something called aliases. What if you don't like that it's called posts and nodes? What if you're building an application that has a UI that's a list of cards and you want your data to come back called a card list and each node you want to be called a card and maybe instead of ID you like the word key or something like that. You can alias your data with GraphQL so you can say, hey, I want posts but when you return it to me, I want it to be a return card list and for each one I want to be called or the list I want to be called cards or whatever and then each ID I want it to be called key and you can see my response. It's the same data that I asked for but now it's aliased with what I asked with what I asked it to be aliased for so I don't have to do that transformation on the client side now. So more aliases and I'm gonna show you what the power of this in a second. So I can ask for two lists of different things with the same shape so I can ask for list of posts but their node for ID it's gonna be called key, the title, description, and link and then this one I'm asking for categories but I want it to have the same shape, right? So my post I'm gonna get back a list of cards, key, title, description, link and then my categories, same exact shape. So this gives us some pretty powerful things to do with components so we're actually gonna look at what this looks like in action now. So I can send this query that I just showed you it's a query asking for a list of posts and a list of categories. I can build one card component that expects a key, a title, the type name, the description, and the link and then I can render this list so on one side you have posts, on the other side you have terms, right? So it's one component, right? I can, I now don't have to build a specific component for my terms and a specific component for my posts, right? I can use the same component in both cases. So this is just a quick example showing like this is the actual react component that you're seeing rendered right here and in both cases terms, posts, works, right? So variables, good thing to know about GraphQL, it's best practice to keep them static strings which means there's no actual variable part of the request itself. So variables are a second part of the request. This IDE gives you a pain to edit these variables so you can declare a variable statically in your request string so in this case I'm gonna say hey, I wanna accept the variable first and it's gonna be an integer and this validates that, knows that first would be an integer and then, so now I can keep my request a static string so I can have like a library of requests or whatever in my application and then if I need to make it dynamic I can pass variables as a separate part of the request. GraphQL knows how to validate first that your variables are what they're supposed to be. In my case, first is supposed to be an integer so before execution, GraphQL says hey, is this variable an integer? If so, cool, go ahead and process. If not, send an error back. So look at more variables. This one's getting a little crazy because we have a lot of variables here now. So if I execute, I'm not passing any variables so it's just gonna go back to the defaults, right? But I can fill in some of these things like first one where, let's see, I think I'm the author on these, I don't know, maybe. Yeah, so Jason is not the author on any of these, right? Maybe it's my full name, I can't remember. Yeah, but you can narrow the scope of what you're asking for. And that was actually a good example. If I send my stuff in invalid format, like that was invalid JSON for my variables, I get this error back, a pretty helpful error telling me, hey, that's actually unexpected. But yeah, so I can use these variables to make my app dynamic while keeping my query string static, which is super powerful. Another really cool thing is this thing called directives. So you could actually add logic into your queries to even request fields or not request fields based on certain conditions. So this directive here is gonna say, if this variable is true, include this field. If this variable is false, don't include it. So, and that variable can be set by whatever you want, like is the user logged in or does the user have certain permissions or is it Tuesday, right? Like whatever, I don't know. Like whatever you want, if you can set this to true or false, you can dictate what data you're gonna get back conditionally. So if I just set this to false, send that same request, you'll see this page info and this link field will not be included this time. So page info gone, link gone, right? So I can, at my query layer, just set, here's what I want in this case, here's what I want in this case. So really powerful stuff. And this page info actually has to do with pagination and this is where cursors, edges, and edges nodes and cursors come in. So if I wanna paginate my data, if I get a list of items, I can ask for page info. I don't have much data in this environment, so has next page, has previous page, I don't have that much data. But I would get an indication that yeah, there is another page and then I can use this cursor as a reference point to where in the data set I am, GraphQL will use that and go to the next one. So I can do something like this. So I want the first post after this cursor. So if the live demo gods don't hate me, I should get, so I'm asking for the post after WordCamp Phoenix, so that should, if everything goes well, be hello world. So I'm just asking for the first one after this one. And there you go, hello world. So that's how you paginate, right? So in something like React or whatever, you'll cache that cursor value and then on your next request, you say hey, give me the next X amount after this. Another powerful thing is unions. Sometimes you don't know what the data is until execution time. A good example of this would be media item parent, right? An image can be attached to a post or it can be attached to a page or it can be attached to a product or whatever, a user, like who knows. So media item parent, well, probably not user, maybe. Anyway, sometimes you don't know what you're gonna get back until execution time. So this is a quick example as well. I want a list of all terms on this post regardless of taxonomy. But if it's a category when you get these terms, I want the ID of the name and the slug, but if it's a tag, I want the slug in the link. So I can execute this and you'll see here on category I get ID name and slug, on tag I just get slug in link. So like a common use case would be like search, right? If you search across types and maybe you wanted a different view presented for different types of content, you can say hey, I wanna search but I might get different types back and depending on the type, I want different data. So that's that. We'll look super quick at some extending and then I gotta wrap up. So custom post type support, I know just out there itching like how do I support my custom post types in GraphQL? Pretty easy. So just a couple lines here. So in this case, I'm gonna register a post type book. We just say show in GraphQL true, give it a couple properties, register a post type or a taxonomy genre, connect that to books. Then I'm gonna add one field price that's gonna return post meta of price on the post ID that I query. So now I can query for books. So this is pretty cool. I have two books so I'm gonna query for the ID of the title, the genres, what not. I get my book, WordCamp Phoenix, genre's best WordCamp ever. Host of WordCamp US 2019, okay. Price is $9.99, okay. Using GraphQL with WordPress, priceless. Okay, cool, I get it. So that's this in action now too. So I can run this query for posts. Oh, whoops, got the wrong component in this one. My demo data's wrong on that. Anyway, but this is that in action, right? So I can run that query, get my books. I can get multiple things. I get the title, I get a custom meta field. I get a featured image URL. I get the title, I get the avatar of the author and I get a list of term names all in a one request, like very simple request. So my time's actually out. I did have some demos on mutations because you can actually write data with GraphQL as well, not just query for data and it respects authentication authorization, but I am out of time. So talk to me in the happiness lounge if you wanna find out more, thanks. Three minutes. What's that? Oh, yeah, all right, let's see. Oh, maybe I lied. I don't think I actually put it in here. Let's see, I thought I did, but yeah. Yeah, find me at the happiness bar. I'll show you mutations if you're interested. What's that? Like in the request. Yeah, that's probably where fragments would come in then. So you define just like a piece of it, use that fragment and then comment your fragment. Yeah, yeah, that's what I would probably suggest, yeah. Yeah, so the question here was writing data. So WP GraphQL by default is gonna bind stuff to WordPress, but it doesn't have to. I did have another example that I didn't get to that query data from icanhasdadjoke.com, right? So you can query dad jokes from WordPress. So you can also store data wherever you want. By default, what comes out of the box is support for the WordPress data stuff. So post users, terms, things like that. If you had a custom table or an external data source, like I don't know, you could even mutate data in Google Analytics if you wanted to, right? Through a request like this. So it's agnostic to the data store. By default, it's gonna give you a lot of help with WordPress data, but you can customize it to do whatever you want. What's that? Cool. Yeah, so it would have to be registered right now. So like one example that I went by really fast, but right here for now, this is an example of adding a price field to the book type in the graph, and then I can resolve this however I want. In my case, I'm just resolving to get post meta. I do have some prototype plugins that bring ACF support to GraphQL or field manager support. They're kind of broken right now, so don't use them, unless you want to contribute to them, which would be awesome. Depends on, so the question was, is it beneficial to disable the default REST API? I think it depends on what you're building and what your needs are. We use GraphQL for a lot of stuff, but we have native mobile apps that still hit our REST endpoints for some things. So if we had zero dependencies on it, I don't know, maybe we would disable it, I don't know. We use both currently still. Not yet. Dave Ryan, I know, has expressed interest. I don't use multi-site at all. Theoretically, it should not be that hard, but if you use multi-site and are interested, chat with me and we'll figure some out. Oh yeah, yeah, yeah. Good question. Those were the slides I didn't get through. Shout out to contributors too, didn't get here, sorry. And then here's two examples. There are more, work.courts.com and hopelab.org are two examples that use it. And I'll show you just super, super fast. One cool thing. They're using a client called Apollo that actually monitors your queries in DevTools. So as I navigate around, I can see what queries they're running. And this is not a site I'm affiliated with, by the way. But then I can actually see what queries they're using to hydrate their data. And then to debug, I can run this query straight here in my DevTools. Like, there's awesome tooling around GraphQL, which I didn't even get to highlight. Last one, I think. For the queer language itself, GraphQL.org, for the PHP library that's under my plug-in, GraphQL-php.com or .org, I think. And then my site is just wpgraphql.com. All right, thank you guys.