GraphQL Filters and Sorts

GraphQL is well suited for Drupal since Drupal has a data schema that can be mapped to a schema for GraphQL. The GraphQL Drupal contributed project provides this mapping yet it is rapidly changing and has no documentation. Tutorials are quickly out of date. Some of the more recent changes are covered in this article. It expands on the Decoupled Drupal, GraphQL and React article.

Filtering in GraphQL

The previous article has instructions for setting up decoupled Drupal.  Starting from there, we are going to delete the articles generated previously and then generate articles and pages.

drush genc 50 --kill

Once the content is generated, refreshing the React app results in an error. This is because of missing fields for content types that are not articles. So the next step is to filter the content down to just articles. The syntax for adding filters changed on February 9, 2018 and has not been documented.  The GraphQL Explorer can be used to construct the filter.

GraphiQL Explorer

On the left is the original query without the filter. On the right is the result of the query. The empty braces are for content that are not articles. Now replace the nodeQuery line with the following filter.

nodeQuery(filter: {
  conjunction: AND
  conditions: [{
    field: "status"
    value: "1"
  }, {
    field: "type"
    value: "article"
  }]
}) {

There are two filters above. The first one is to only retrieve published content. The second filter is for article content. These are specified under the conditions. The conjunction specifies that both conditions are to be applied. The groups key is used to combine conjunctions. Press the arrow to generate the result and the empty brackets should disappear. Now the filter needs to be added to the React app. In the App.js for the ArticlesView, change the query to:

<Query
  query={gql`
    {
      nodeQuery(filter: {
        conjunction: AND
        conditions: [{
          field: "status"
          value: "1"
        }, {
          field: "type"
          value: "article"
        }]
      }) {
        entities {
          ...on NodeArticle {
            nid 
            title
            body {
              value
            } 
          } 
        } 
      } 
    }
  `}
>

With this change the React app should no longer have any errors.

GraphQL sorting

In addition to filtering, another common requirement is to sort the results. The sort can first be added to GraphiQL Explorer if that helps but I will skip it here. Change the ArticlesView in the App.js to add the sort as follows.

nodeQuery(filter: {
  conjunction: AND
  conditions: [{
    field: "status"
    value: "1"
  }, {
    field: "type"
    value: "article"
  }]
}, sort: [{
  field: "created"
  direction: DESC
}]) {

Paging

A couple of other useful keys are often used for paging. These keys are limit and offset. Update the code as follows:

}, sort: [{
  field: "created"
  direction: DESC
}], limit: 10, offset: 10) {

Saving the file should automatically update the React app. Try some other values for the limit and offset to see how they work.

The last item that is needed for a pager is an overall count. Since this article only covers the information required for a pager but does not include the code to construct it, the count will be shown in two different ways. The first is in GraphiQL. Cut and paste the up to date query from App.js to GraphiQL. Then add the count just before the entities.

}], limit: 10, offset: 10) {
  count
  entities {

Then press the run button and on the right should be something like:

{
  "data": {
    "nodeQuery": {
      "count": 28,
      "entities": [
        ...

Making the same change in App.js and the browser console shows that the count is retrieved.

Count query result

This should cover the common alterations of a basic GraphQL query already containing the fields. It also shows how to use the GraphiQL Explorer and taking the query and placing it in the React app.

Categories