skip to Main Content

Optimizing WPGraphQL for WordPress VIP

If you host your site with WordPress.com VIP, you can (and should) take advantage of the cached functions they provide to improve performance of some WordPress core uncached functions.

If you’re using WPGraphQL in a WordPress.com VIP environment and want to have WPGraphQL take advantage of some of these functions, you can do so pretty easily.

In WPGraphQL, the TermObjectType, which is used for terms (categories, tags, custom taxonomies) has a link field, which uses the uncached get_term_link function in the resolver.

WordPress.com VIP provides an alternative cached function: wpcom_vip_get_term_link.

Our goal here is to:

  • Find all termObjectTypes
  • Filter the resolver for the `link` field on those types, replacing the default resolver with our optimized resolver.

Let’s do this:

First, let’s only hook our functionality in after the Allowed Taxonomies have been registered and setup for WPGraphQL to make use of.

add_action( 'graphql_generate_schema', 'your_prefix_filter_term_object_fields', 10, 1 );

Now, let’s get the Taxonomies that are registered as allowed to show in GraphQL, and we’ll loop through them and filter their fields.


function your_prefix_filter_term_object_fields() {
  
  // Get the allowed taxonomies (taxonomies with "show_in_graphql" => true)
  $allowed_taxonomies = \WPGraphQL::get_allowed_taxonomies();
  
  // Loop through the allowed taxonomies, so that we can filter the fields for each termObjectType for each taxonomy
  if ( ! empty( $allowed_taxonomies ) && is_array( $allowed_taxonomies ) ) {

     foreach( $allowed_taxonomies as $taxonomy ) {

         // Get the taxonomy object as we'll need the "graphql_single_name" property to use in the filter
         $tax_object = get_taxonomy( $taxonomy );

         if ( ! empty( $tax_object->graphql_single_name ) ) {
             add_filter( "graphql_{$tax_object->graphql_single_name}_fields", 'your_prefix_replace_term_link_resolver', 10, 1 );
         }
     }
}

Now, we’re at a point where each termObjectType (category, tag, etc) will have it’s fields filtered. So now we need to alter the $fields to replace the resolver for the link field to make use of the cached function we have available in the VIP environment.

// This is the callback for our filter on the termObjectType fields. 
// We get the $fields passed to us and we want to replace the "resolve" function for the "link" field
function your_prefix_replace_term_link_resolver( $fields ) {
    if ( ! empty( $fields['link'] ) ) {
        $fields['link']['resolver'] = function( \WP_Term $term, $args, $context, $info ) {

            // Get the term link using the VIP cached function
            // You could even wrap this with a "function_exists( 'wpcom_vip_get_term_link' )" and fall back to the standard "get_term_link" function
            // to make sure things work when running in an environment where the VIP functions are not present
            $term_link = wpcom_vip_get_term_link( $term->term_id );

            // If the response was valid, return it, otherwise return a null response. 
            // You might also want to throw an exception if the response was a WP_Error
            return ( ! empty( $term_link ) && ! is_wp_error( $term_link ) ) ? $term_link : null;
        
        }
    }

   // Return the $fields, altered or not
   return $fields;
}

There we have it. We now have our link field on termObjects resolving using a WordPress.com VIP cached function!

Now, we can execute a query like so and know that the link field will be more performant.

{
  tags{
     edges{ 
       node{
          id
          name
          link
       }
     }
  }
}
This Post Has 2 Comments
    1. Paul,

      Good suggestion!

      For this particular one, it’s already been fixed in core as of 4.8, so this modification isn’t even necessary anymore and VIP has already announced that they are deprecating their “wpcom_vip_get_term_link ” function.

      Moving forward I’ll definitely implement some sort of cached functions within the WPGraphQL codebase. (unless I know it’s on the near-future-radar for being fixed in a core release). I already started with the most recent PR that adds a cached function for getting a post by it’s URI: https://github.com/wp-graphql/wp-graphql/pull/208/files#diff-6cb4d5837d2d97520852669e00ca83b1R542

Leave a Reply

Share This
Back To Top