Index
Edit

GraphQL (Public Beta)

Sanity.io already has powerful APIs for querying, patching, and mutating data in the real-time content backend. Going forward we will support GraphQL as a way to query content in addition to our GROQ API. This feature will be available for all users of Sanity.io.

Gotcha

Big word of warning: Things are likely to change. You probably don't want to build your production environment on top of this until we've stabilized the API.

This does not apply to APIs for introspection, for instance the Gatsby source plugin.

Strict schemas

The schemas for Sanity Studio are a bit more flexible than what GraphQL is able to represent. That means that we can't promise that you'll be able to deploy a GraphQL API without any changes to your Sanity projects. Therefore, you may have to do a few changes (usually these are backward-compatible and does not require any data migration).

You may find that “anonymous“ object types have to to be given a name and declared in the top-level scope. Take this example:

// schemas/blogPost.js
export default {
  name: 'blogPost',
  title: 'Blog post',
  type: 'document',
  fields: [
    // ... other fields ...
    {
      name: 'sponsor',
      title: 'Sponsor',
      type: 'object',
      fields: [
        {
          name: 'name',
          title: 'Name',
          type: 'string'
        },
        {
          name: 'url',
          title: 'URL',
          type: 'url'
        }
      ]
    }
  ]
}

In the code above, the sponsor field is an object type declared inline. This means it cannot be used outside of the blogPost type. This is not compatible with GraphQL – all object types have to be defined in a global scope. To fix this, you should move the sponsor declaration to a separate file and import it into your schema explicitly, then have the sponsor field refer to it by name. Example:

// schemas/blogPost.js
export default {
  name: 'blogPost',
  title: 'Blog post',
  type: 'document',
  fields: [
    // ... other fields ...
    {
      name: 'sponsor',
      title: 'Sponsor',
      type: 'sponsor'
    }
  ]
}

// schemas/sponsor.js
export default {
  name: 'sponsor',
  title: 'Sponsor',
  type: 'object',
  fields: [
    {
      name: 'name',
      title: 'Name',
      type: 'string'
    },
    {
      name: 'url',
      title: 'URL',
      type: 'url'
    }
  ]
}
Pro-tip

While "lifting"/"hoisting" the type to the top-level scope, it can be helpful to consider whether the type should be altered to make it more reusable in other contexts. If you think the type is only relevant to the specific schema type, consider prefixing it to make it clearer (eg. blogPostSponsor in the above case).

Deploying the GraphQL API

First, make sure you're on the latest Sanity version by running npm i -g @sanity/cli && sanity upgrade in the command line.

Run sanity graphql deploy from your Sanity Studio project folder. This will deploy an API for the dataset configured in sanity.json. If you want to deploy to a different dataset, use the --dataset flag, eg: sanity graphql deploy --dataset staging.

Keep in mind that changing the schema in your local Sanity studio does not automatically change the GraphQL API - you'll have to run sanity graphql deploy to make the API reflect the changes.

Security

The GraphQL API generally has the same rules as the GROQ API - dataset visibility is respected. Authenticated users see only the documents they have access to.

However; the schema of your project is public, so all types and fields can be introspectable by anonymous users.

Caching / CDN

The de-facto standard for transporting GraphQL operations to the server is by sending a POST-request with a request body that can contain both queries and mutations. What this means is that for the time being, GraphQL queries cannot use the CDN API.

Mutations

We don't currently support mutations. This will be implemented at some point in the future. If you have suggestions on which mutations you'd want to see, let us know. The current working theory is exposing the same low-level mutation API that we currently have in Sanity.

Schema generation issues

Since the schema is generated in node.js instead of in a browser environment, certain imported modules might cause issues. Things that reference the window in a global context is a prime example. If you encounter issues, we'd be interested in hearing which modules cause problems to see if we can work around them.

GraphQL endpoint

Run queries against https://<yourProjectId>.api.sanity.io/v1/graphql/<dataset>/default

Upcoming changes

From a recent “poll” on the Community Slack, it looks like we will be changing the filter system for document collections. Instead of {where: {age_gt: 30}}, we'll probably use something along the lines of {where: {age: {gt: 30}}}.

How to provide feedback

If you have questions, thoughts or praise - feel free to let us know in the #graphql channel on Slack.


Previous: Query Cheat Sheet - GROQNext: Transactions