GraphQL & WordPress
JS for WordPress Online Conference
Jason Bahl | @jasonbahl
Me.
- Senior WordPress Engineer at Digital First Media in Denver, CO
- Denver native
- WordPress Developer for 9+ years
- I love WordPress, and Open Source in general
- Creator & maintainer of WPGraphQL
This Talk.
- What is GraphQL?
- Compare GraphQL with existing WordPress APIs
- How to use GraphQL with WordPress
- Use GraphQL with Gutenberg
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 developer tools
GraphQL
A Query Language for your API
GraphQL
Open Source Specification
Created & maintained by Facebook
Used in production by Facebook since 2012








GraphQL
Graph != Graph Databases
Graph != Graph Search
Graph = Application Data Graph
QL = Query Language
GraphQL: A Query Language for Your Application Data Graph
GraphQL
{
me {
name
}
}
{
data: {
me: {
name: "Jason Bahl"
}
}
}
GraphQL Query
GraphQL Result
Post
Category
Category
Category
Post
title
"Hello World"
title
"GoodBye Mars"
Image
Image
Image
name
"news"
name
"crime"
name
"sports"
Image
WordPress as an Application Data Graph
GraphQL
GraphQL lets us pick trees out of the Application Data Graph
GraphQL
query {
post(id: "...") {
title
link
categories {
nodes {
name
}
}
}
}
{
data: {
post: {
title: "Hello World!"
link: "http://site.com/hello-world"
categories: {
nodes: [
{
name: "sports"
},
{
name: "crime"
}
]
}
}
}
}
Post
Category
Category
Category
Post
title
"Hello World"
title
"GoodBye Mars"
Image
Image
Image
name
"news"
name
"crime"
name
"sports"
Image
Comparing APIs

Comparing APIs
Data Requirements:
- List of posts
- author
- name
- avatar (size: 50)
- url
- site
- name
- link
- followLink
- title
- featuredImage (width: 300)
- url
- excerpt








Comparing APIs

<?php
$posts = new WP_Query(
array(
'post_type' => 'post',
'posts_per_page' => 4,
'post_status' => 'publish'
)
);
# Loop through the posts
<?php
# Author Data
$author = get_the_author();
$author_name = $author->display_name;
$avatar = get_avatar_data( $author->ID );
$avatar_url = $avatar->url;
# Site Info
$sites = wp_get_post_terms(
$post->ID, 'sites'
);
$site_name = $sites[0]->name;
$site_link = get_term_meta(
$sites[0]->term_id,
'link',
true
);
# Follow Link
$follow_link = your_follow_link_func();
# Title
$title = get_the_title();
# Featured Image
$img = get_the_post_thumbnail_url(
$post->ID,
array( 300 )
);
# Excerpt
$excerpt = get_the_excerpt();








Comparing APIs
# Posts
# Assumes follow link is a registered
# field on the post endpoint
HTTP GET
/wp-json/wp/v2/posts?per_page=4
$posts.map((post) => {
$title = post.title;
$excerpt = post.excerpt;
$follow = post.followLink;
});











# Authors
HTTP GET
/wp-json/wp/v2/user/{posts[0].author}
/wp-json/wp/v2/user/{posts[1].author}
/wp-json/wp/v2/user/{posts[2].author}
/wp-json/wp/v2/user/{posts[3].author}
/wp-json/wp/v2/user/{posts[0].author}/avatar
/wp-json/wp/v2/user/{posts[1].author}/avatar
/wp-json/wp/v2/user/{posts[2].author}/avatar
/wp-json/wp/v2/user/{posts[3].author}/avatar
# Sites
# Assumes REST API was customized to show
# The "Sites Custom Taxonomy" IDs on the
# Post endpoint
HTTP GET
/wp-json/wp/v2/site/{posts[0].sites[0]}
/wp-json/wp/v2/site/{posts[1].sites[0]}
/wp-json/wp/v2/site/{posts[2].sites[0]}
/wp-json/wp/v2/site/{posts[3].sites[0]}
# Featured Images
HTTP GET
/wp-json/wp/v2/media/{posts[2].featured_media}
/wp-json/wp/v2/media/{posts[3].featured_media}
Comparing APIs







query {
posts(first: 4) {
edges {
node {
}
}
}
}
author {
name
avatar(size: 50) {
url
}
}
followLink
title
featuredImage(width: 300) {
url
}
excerpt
site {
name
link
}
Data Requirements:
- List of posts
- author
- name
- avatar (size: 50)
- url
- site
- name
- link
- followLink
- title
- featuredImage (width: 300)
- url
- excerpt
Observed Pain Points
Completely different experience using PHP and REST
# WordPress, PHP with WPGraphQL Active
$query = '
{
posts {
edges {
node {
id
title
link
}
}
}
}
';
$data = do_graphql_request( $query );
# JavaScript, using Fetch
const query = `{
posts {
edges {
node {
id
title
link
}
}
}
}
`;
fetch('site.com/graphql', {
method: "POST",
body: {
query: query
}
});
Similar experience using GraphQL in PHP, or any other language
<?php
# Author Data
if ( $posts->have_posts() ) {
while ( $posts->have_posts() ) {
$posts->the_post();
$author = get_the_author();
$author_name = $author->display_name;
$avatar = get_avatar_data(
$author->ID
);
$avatar_url = $avatar->url;
}
}
# Author Data
HTTP GET
/wp-json/wp/v2/user/{posts[0].author}
/wp-json/wp/v2/user/{posts[1].author}
/wp-json/wp/v2/user/{posts[2].author}
/wp-json/wp/v2/user/{posts[3].author}
/wp-json/wp/v2/user/{posts[0].author}/avatar
/wp-json/wp/v2/user/{posts[1].author}/avatar
/wp-json/wp/v2/user/{posts[2].author}/avatar
/wp-json/wp/v2/user/{posts[3].author}/avatar
# CURL
$ curl -XPOST
-H "Content-Type:application"
-d '{"query":"{
posts{
edges{
node{
id
title
link
}
}
}
}"}'
http://site.com/graphql



Observed Pain Points
Lots of Functions / HTTP Requests
HTTP GET
/wp-json/wp/v2/posts?per_page=4
/wp-json/wp/v2/user/{posts[0].author}
/wp-json/wp/v2/user/{posts[1].author}
/wp-json/wp/v2/user/{posts[2].author}
/wp-json/wp/v2/user/{posts[3].author}
/wp-json/wp/v2/user/{posts[0].author}/avatar
/wp-json/wp/v2/user/{posts[1].author}/avatar
/wp-json/wp/v2/user/{posts[2].author}/avatar
/wp-json/wp/v2/user/{posts[3].author}/avatar
/wp-json/wp/v2/site/{posts[0].sites[0]}
/wp-json/wp/v2/site/{posts[1].sites[0]}
/wp-json/wp/v2/site/{posts[2].sites[0]}
/wp-json/wp/v2/site/{posts[3].sites[0]}
/wp-json/wp/v2/media/{posts[2].featured_media}
/wp-json/wp/v2/media/{posts[3].featured_media}
<?php
$posts = new WP_Query(
array(
'post_type' => 'post',
'posts_per_page' => 4,
'post_status' => 'publish'
)
);
if ( $posts->have_posts() ) :
while( $posts->have_posts() ) :
$posts->the_post();
$author = get_the_author();
$author_name = $author->display_name;
$avatar = get_avatar_data( $author->ID );
$avatar_url = $avatar->url;
$sites = wp_get_post_terms(
$post->ID, 'sites'
);
$site_name = $sites[0]->name;
$site_link = get_term_meta(
$sites[0]->term_id,
'link',
true
);
$follow_link = your_follow_link_func();
$title = get_the_title();
$img = get_the_post_thumbnail_url(
$post->ID,
array( 300 )
);
$excerpt = get_the_excerpt();
endwile;
endif;
Single GraphQL Request


# WordPress, PHP with WPGraphQL Active
$query = '
{
posts {
edges {
node {
id
title
link
}
}
}
}
';
$data = do_graphql_request( $query );
- Constantly over fetching and under fetching
- Lots and lots of HTTP requests
- Tight client-server coupling
- Implicit Requests Make Maintenance Difficult
- Maintaining Documentation
- Versioning is difficult

- Fetch exactly what you need, nothing more, nothing less
- Multiple resources in a single HTTP request
- Decoupled client-server relationship
- Explicit requests ease maintenance
- Self Documenting Schema / Type System
- Easy, pain free versioning


How to use GraphQL with WordPress



WPGraphQL is a free, open-source WordPress plugin that provides an extendable GraphQL schema and API for any WordPress site.
We have stickers!
Adding the Plugin to WordPress

- Visit Github:
- Star the Repo
- Tweet about how awesome it is to be able to use GraphQL with WordPress
- Clone or Download the plugin
- Install & Activate

Install & Activate the Plugin



DEMOS
Contributors















WPGraphQL in the Wild




WPGraphQL

Website: https://wpgraphql.com
Github: https://github.com/wp-graphql
Twitter: https://twitter.com/wpgraphql
GraphQL & WordPress - JS for WP Online Conference
By Jason Bahl
GraphQL & WordPress - JS for WP Online Conference
WordPress + GraphQL presentation for the JS for WordPress online conference hosted by Zac Gordon.
- 1,157