Date

Upgrading to v0.3.0

WPGraphQL v0.3.0 is one of the most substantial releases to date for the plugin. You can read more about what was included in this release here and here.

Test in Staging Environment

It’s best practice to test plugin updates in staging environment, but I want to re-iterate that again here. Make sure you thoroughly test things when you update this plugin to v0.3.0, especially if you have any custom code that extends the Schema in any way.

Break: “roles” field on User type has changed shape

The User Type in the Schema previously had a roles field that returned a list of role names as strings.

Pre v0.3.0

{
  users {
    nodes {
      roles
    }
  }
}

Would return something like the following:

{
  "data": {
    "users": {
      "nodes": [
        {
          "roles": [ 'administrator' ]
        }
      ]
    }
  }
}

v0.3.0

In v0.3.0, the roles field has changed to a Connection of roles. The query would change to something like the following:

{
  users {
    nodes {
      roles {
        nodes {
          name
        }
      }
    }
  }
}

This change was made largely because Roles aren’t _really_ properties of a user. Roles are defined as entities on their own, and Users have a connection to one or more roles.

Break: Resolvers return models instead of WP_* instances

If you were extending some of the core Types in the Schema by adding fields, the first argument passed to the resolver used to be an instance of a core WP_* class. For instance, the Post Type would pass an instance of WP_Post down to field resolvers on that Type. Now, it will pass an instance of \WPGraphQL\Model\Post.

Here’s an example of a Field that may have been registered to the “old” version of the Schema:

register_graphql_field( 'Post', 'myNewField', [
  'type' => 'String',
  'resolve' => function( \WP_Post $post, $args, $context, $info ) {
    $data = get_post_meta( $post->ID, 'some_data', true );
    return $data ? data : null;  
  }
] );

Here, we see the first argument passed down is a \WP_Post. In v0.3.0, that would be a \WPGraphQL\Model\Post like so:

register_graphql_field( 'Post', 'myNewField', [
  'type' => 'String',
  'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
    $data = get_post_meta( $post->ID, 'some_data', true );
    return $data ? data : null;   
  }
] );

The following resolvers changed:

  • \WP_Post is now \WPGraphQL\Model\Post
  • \WP_User is now \WPGraphQL\Model\User
  • \WP_Comment is now \WPGraphQL\Model\Comment
  • \WP_Term is now \WPGraphQL\Model\Term

The full list of Models now available, that replaced what was there previously, is:

  • \WPGraphQL\Model\Avatar
  • \WPGraphQL\Model\Comment
  • \WPGraphQL\Model\CommentAuthor
  • \WPGraphQL\Model\Menu
  • \WPGraphQL\Model\MenuItem
  • \WPGraphQL\Model\Plugin
  • \WPGraphQL\Model\Post
  • \WPGraphQL\Model\PostType
  • \WPGraphQL\Model\Taxonomy
  • \WPGraphQL\Model\Term
  • \WPGraphQL\Model\Theme
  • \WPGraphQL\Model\User
  • \WPGraphQL\Model\UserRole

Depending on how you were extending the Schema, this may or may not have any affect on you.

Break: DataSource methods

The signature of DataSource methods have changed. If you were calling any DataSource methods in your extensions, you’ll likely need to refactor a bit. We recommend checking out the changes to that file so you understand all the changes for the methods you’re using, but here’s a quick example pointing out the difference:

Pre v0.3.0:

DataSource::resolve_post_object( $id, $post_type );

v0.3.0

DataSource::resolve_post_object( $id, $context );

The specific way in which the signature for the DataSource method changed may be different depending on the method. If you’re calling any of these methods, check how it changed to be sure you’re using it the new way.

Break: Connection Resolver Classes

If you were making use of the ConnectionResolver classes in anyway, they’ve been completely revamped. They’ve been moved into the /Data/Connection directory, and are now stateful classes instead of classes with static methods. They are now much easier to digest and understand how to extend and create your own Connection Resolvers.

I won’t cover changes in detail here, but if you wrote any custom Connection Resolvers, and the new way of doing it doesn’t make sense after reading the new code, feel free to reach out and we can do our best to help you update.

Break: All kinds of restricted content is actually restricted now

With the introduction of the Model Layer, many fields and nodes that were previously accessible in public requests have now been restricted.

For example, our documentation previously mentioned that fields such as email on the User type was publicly exposed, and that if you wanted to hide it, you could do so via filter.

We’ve implemented a formal Model Layer that now handles restrictions like this out of the box, so fields that you may have been querying before, might not be returned anymore. Depending on your use case, this may be a break to you application, so it’s something to get familiar with.

How the Model Layer Works

We’ve written some docs on the Model Layer, but the general idea is that if you download install WordPress with nothing active but a standard `twenty-*` theme, the data that is exposed to a user should be the same data that is exposed to a GraphQL request.

For example, a non-authenticated user cannot access draft Posts in a vanilla WP install, so WPGraphQL will not return Draft posts to non authenticated users. (There’s more logic than that, but that’s just an example).

There are dozens of conditions in place that help determine whether fields should or should not be returned to the consumer making the request.

Other Breaking Changes

There might be some other breaking changes that we didn’t cover here. If you read this guide and also get familiar with the latest info on https://docs.wpgraphql.com, but still run into issues that break your application after updating to v0.3.0, please reach out in Slack or Spectrum, or Open a Github Issue and we’ll do our best to help you get upgraded. We also highly recommend getting familiar with the source code of v0.3.0. We’ve commented the code very heavily to help provide an understanding of how everything is working and why it’s working that way.

If you find something you believe is a bug, as usual, please open an issue on Github