Date

WPGraphQL v0.6.0 Release

WPGraphQL v0.6.0 is here!

This release is one of the most significant releases in the history of the WPGraphQL plugin.

Breaking Changes

Before getting into the hype of the release, I want to highlight some prominent breaking changes. A full list can be found in the release notes.

  • A change to pagination of connections was introduced and any plugin/theme that has a class extending the AbstractConnectionResolver will need to add a public method is_valid_offset to support pagination properly. Not adding this method to extending classes will cause errors.
  • Many fields of Post Object Types (Post, Page, Custom) are now only exposed on the Type if that post_type supports the feature. For example, the “page” post type doesn’t support excerpts in core WordPress. Prior to this release you could query the field excerpt when querying for pages. You no longer can ask for the field excerpt on Pages because Pages don’t support excerpts. Posts do support excerpts, so you can query that field on Posts. If you were querying fields that a Post Type didn’t support, this release might break some of your queries.
  • We fixed a bug with settings registered with dashes not properly being mapped to the schema. This fix in behavior could cause a breaking change depending on what types of settings you had registered and were querying from the schema.

New Features

This release focused primarily on Interfaces. A full list of new features can be found on the release notes.

In GraphQL, an Interface is an abstract type that defines a certain set of fields that a type must include to implement the interface.

In WPGraphQL, prior to this release, the only Interface that was defined and implemented was the node interface, which defined the ID field. Any Type, such as Post, Page, Category, Tag, Comment or User, that implements the node interface must have an ID field. And thus, any of these types could also be fetched by ID.

Take the following query for example:

query GET_NODE {
  node(id:"cG9zdDoyMjE5") {
    __typename
    id
    ...on Post {
      title
    }
    ...on Page {
      title
      date
    }
  }
}

In the example query, we pass an ID of a node. If, during execution, the server determines the ID is that of a Post, it will return to us the __typename, id, and title, but if it is determined that the ID is that of a Page, it will return the __typename, id, title and date.

Interfaces allow us to ask for any Type that implements said interface and in response we can ask for the common fields, and can specify the different fields we want based on the Type that is resolved at execution.

This allows for applications to be built with a high level of predictability.

Your application is now able to predict what fields will be returned based on the Type being returned. This type of interaction with an API can eliminate entire classes of bugs.

New Interfaces

After this release, we now have many more interfaces to join the Node interface.

The following are Interfaces introduced in this release:

  • TermNode: Defines fields shared across Terms of any Taxonomy Type
  • ContentNode: Defines common fields shared by Post object nodes. Not all fields of Post Types are common across all Post Types. Each Post Type can register/deregister support for numerous fields. The fields that cannot be different are defined in this interface and all Post types implement this Interface.
  • UniformResourceIdentifiable: Defines a uri field. Implemented by Nodes that can be accessed by URI.
  • NodeWithTitle: Defines a title field. Implemented by post types that support titles.
  • NodeWithContentEditor: Defines the content field. Implemented by post types that support the editor.
  • NodeWithAuthor: Defines the author field, connecting a Node to its author. Implemented by post types that support authors.
  • NodeWithFeaturedImage: Defines the featured image field, connecting a Node to its featured image. Implemented by post types that support thumbnails.
  • NodeWithComments: Defines comment fields. Implemented by post types that support comments.
  • HierarchicalContentNode: Defines hierarchical fields (parent/children). Implemented by hierarchical post types.
  • ContentTemplate: Defines a template field.
  • NodeWithRevisions: Defines revisions fields. Implemented by post types that support revisions.
  • NodeWithExcerpt: Defines the excerpt field. Implemented by post types that support excerpts.
  • NodeWithTrackbacks: Defines fields related to trackbacks and pingbacks. Implemented by post types that support trackbacks.

I cannot provide examples of using every one of these interfaces, but I will cover some examples that should be valuable to WPGraphQL users.

Content Node Interface

The ContentNode interface allows for nodes of different Post Types to be queried in a single connection. Prior to this release, Posts of each type were fetched from their dedicated entry points. For example, you could query for { posts { ...fields } } or { pages { ...fields } }, but now, you can query a single collection spanning many post types.

Here’s an example:

{
  contentNodes {
    nodes {
      __typename
      id
      link
      uri
      ... on Page {
        isFrontPage
      }
    }
  }
}

And we might see results like the following:

{
  "data": {
    "contentNodes": {
      "nodes": [
        {
          "__typename": "Post",
          "id": "cG9zdDoyMjE5",
          "link": "http://acf.local/2020/01/14/test-revisions/",
          "uri": "2020/01/14/test-revisions/"
        },
        {
          "__typename": "Page",
          "id": "cGFnZToxNjQw",
          "link": "http://acf.local/test-page-revision/",
          "uri": "test-page-revision/",
          "isFrontPage": false
        },
      ]
    }
  }
}

In this example, we can see that we are receiving both a Post and a Page in the same connection query, and are able to specify common fields, but also able to specify a specific field we want if the Type is Page.

This flexibility allows WPGraphQL users to create robust User Interfaces with flexibility, but also predictability.

URI Interface

The UniformResourceIdentifiable Interface added in this release allows for any node that can be identified by URI to be queried for from a single entry point.

This is incredibly powerful for headless WordPress applications.

When interacting with a WordPress site, it’s incredibly common for a user to have a URI, a path to a resource. Typically that path is entered into a browser, and WordPress is able to return the proper page for that resource. The template and data displayed by WordPress is different based on the type of resource (page, post, user, term) it is.

WPGraphQL can now interact the same way.

A user can pass a URI to WPGraphQL, and specify what it wants in return based on the Type that the resource resolves as.

The following example shows how to query for a nodeByUri for a Post, Page, Tag, Category and User, specifying different fields for each Type.

{
  page: nodeByUri(uri: "about/") {
    ...URI
  }
  post: nodeByUri(uri: "2019/12/05/test-5/") {
    ...URI
  }
  tag: nodeByUri(uri: "tag/8bit/") {
    ...URI
  }
  category: nodeByUri(uri: "category/alignment/") {
    ...URI
  }
  user: nodeByUri(uri: "author/jasonbahl/") {
    ...URI
  }
}

fragment URI on UniformResourceIdentifiable {
  __typename
  uri
  ... on Page {
    pageId
  }
  ... on Post {
    postId
  }
  ... on Category {
    categoryId
  }
  ... on Tag {
    tagId
  }
  ... on User {
    userId
  }
}

And the response might look like:

{
  "data": {
    "page": {
      "__typename": "Page",
      "uri": "about/",
      "pageId": 1086
    },
    "post": {
      "__typename": "Post",
      "uri": "2019/12/05/test-5/",
      "postId": 1739
    },
    "tag": {
      "__typename": "Tag",
      "uri": "tag/8bit/",
      "tagId": 45
    },
    "category": {
      "__typename": "Category",
      "uri": "category/alignment/",
      "categoryId": 4
    },
    "user": {
      "__typename": "User",
      "uri": "author/jasonbahl/",
      "userId": 1
    }
  },
}

This is incredibly powerful for headless applications that might only have a URI of a resource to identify the resource by. Now headless applications can resolve resources with a high level of predictability, even without knowing the type of resource up front.

What’s next

Now that this monumental release is here, the next release will have a focus on Connections. There are many bugs and new features that we want to address that affect the behavior of connections. Keep an eye out for more details there.