GraphQL for WordPress

Automattic Lunch & Learn

Who Am I?

  • Software Engineer at Gatsby, Inc
  • Denver native
  • WordPress Developer for 10+ years
  • I love WordPress, and Open Source in general
  • Creator & maintainer of WPGraphQL

Jason Bahl
@jasonbahl | @wpgraphql

What This Talk Covers

  • What is WPGraphQL and how does it work?
  • WordPress as an Application Data Graph
  • Efficient Data Fetching with GraphQL
  • Authentication and Authorization with WPGraphQL
  • Challenges of GraphQL

WPGraphQL

GraphQL

{
     viewer {
          name
     }
}

{

     data: {

          viewer: {

               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: "cG9zdDox") {
    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

Efficient Data Fetching

Demo REST vs WPGraphQL

Efficient Data Fetching

Solving the N+1 Problem

Auth with WPGraphQL

  • Authentication
  • Authorization

Auth with WPGraphQL

Auth with WPGraphQL

Demo:

 

  • Try to create a post as unauthenticated user
  • Login with WPGraphQL JWT Auth
  • Create Post with JWT Token

Challenges with GraphQL

Demo:

 

  • Naming Things!
  • Deeply Nested Queries
  • Caching

Resources:

GraphQL for WordPress - Automattic Lunch & Learn 8/26/2019

By Jason Bahl

GraphQL for WordPress - Automattic Lunch & Learn 8/26/2019

Slides for WPGraphQL Presentation for the Lunch and Learn with Automattic

  • 1,220