Quick Introduction to GraphQL with the Contentstack SaaS Headless CMS

This blog post provides pointers for using GraphQL with the Contentstack SaaS headless CMS. I am not an expert on or proponent of GraphQL, but these are some things I have learned from working with Contentstack. GraphQL is a data query and manipulation technology intended for HTTPS service APIs that accept and return JSON. You can use GraphQL interactively, such as to generate ad hoc reports through the CMS user interface or Postman, or through the HTTPS API. In some cases, using GraphQL may be preferable to using other content delivery APIs. GraphQL can be optimal for Jamstack applications that hydrate pages with data from the CMS.

Start by reviewing the documentation:

You can use GraphQL to query for entries in a content delivery environment of a Contentstack repository (“stack”). You can use GraphQL in content delivery environments only; there is no GraphQL implementation for the content management API.

You can use the Contentstack UI to assemble and run queries. At https://app.contentstack.com, access the stack, click the Settings icon at the bottom left, and then click GraphQL Explorer. The GraphQL query builder in the CMS user interface uses the content delivery token that you select at the top right of the user interface. The screens captured in this blog post access an environment using the token named contentdelivery.

If you do not have access to a stack, you can evaluate this one:

Contentstack exposes each content type as two resources: one named after the identifier of the content type and the other adding the all_ prefix. If you do not know the identifier of the entry to retrieve, then use the resource with the all_ prefix. The assets and all_assets resources expose information about media assets.

You can use the query provided at the following link to view the GraphQL schema representation of the stack, although the schema may be more readable to machines than humans:

Schema

GraphQL returns only the data explicitly requested. Queries must specify the content types and identifiers of individual fields to retrieve. Whether written in advance or constructed at runtime (for example, from a schema), to retrieve any significant data, queries must be aware of the content types and the fields that they contain.

To retrieve data from entries, query the resource named after the content type with the all_ prefix. For example, to access the homepage content type, query the all_homepage resource. You can specify the “total” parameter to retrieve the count of entries matching your criteria. You can click through the UI to specify criteria for a “where” clause, such as to match the identifier of a single entry, and the individual fields to retrieve. In the query, the “items” block contains the list of fields to retrieve, where Contentstack groups appear as nested elements in this block. The following retrieves the number of entries (“total”) as well as the value of the title field and the value in the URL field in the pagedata group for all entries of the homepage content type.

{
  all_homepage {
    total
    items {
      title
      pagedata {
        url
      }
    }
  }
}

Results:

{
  "data": {
    "all_homepage": {
      "total": 1,
      "items": [
        {
          "title": "HeadlessArchitect.net Home Page",
          "pagedata": {
            "url": "/"
          }
        }
      ]
    }
  }
}

To retrieve the count, title, and URL of entries that have a value of /child in the URL field of the pagedata group in the page content type:

{
  all_page(where: {pagedata: {url: "/child"}}) {
    total
    items {
      title
      pagedata {
        url
      }
    }
  }
}

Results:

{
  "data": {
    "all_page": {
      "total": 1,
      "items": [
        {
          "title": "Child Page",
          "pagedata": {
            "url": "/child"
          }
        }
      ]
    }
  }
}

The “where” clause supports numerous operators as described in the Contentstack documentation and available through the Contentstack query builder UI.

One advantage of GraphQL is that you can retrieve data from multiple content types in a single call rather than retrieving entries from each content type separately. In GraphQL, simply chain the queries together within the outermost brace character ({), again specifying exactly which values to retrieve. In this case, the homepage and page content types share the data structure defined by the pagedata group field in Contentstack. The following receives counts, titles, and URLs from entries of these content types.

{
  all_homepage {
    total
    items {
      title
      pagedata {
        url
      }
    }
  }
  all_page {
    total
    items {
      title
      pagedata {
        url
      }
    }
  }
}

Results:

{
  "data": {
    "all_homepage": {
      "total": 1,
      "items": [
        {
          "title": "HeadlessArchitect.net Home Page",
          "pagedata": {
            "url": "/"
          }
        }
      ]
    },
    "all_page": {
      "total": 2,
      "items": [
        {
          "title": "Child Page",
          "pagedata": {
            "url": "/child"
          }
        },
        {
          "title": "Grandchild",
          "pagedata": {
            "url": "/child/grandchild"
          }
        }
      ]
    }
  }
}

Contentstack provides a collection of queries that you can easily use in Postman.

Postman

To run queries through the API as opposed to the CMS UI, you may want to use an SDK from Contentstack, or you can call the GraphQL HTTPS endpoints directly. In either case, you must specify the Contentstack API endpoint such as https://graphql.contentstack.com, a stack identifier (API key), the name of a content delivery environment to query, and a delivery token that allows access to that environment.

Note that at some scale it is generally optimal to employ a third-party search engine to query data indexed from the CMS rather than using GraphQL or content delivery APIs to locate entries.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: