Skip to Content

Purging API

Stellate automatically creates a custom GraphQL API, the so-called Purging API, for your service that allows you to purge your cache. Purging the cache globally takes at most 150ms.

To try the purging API, head to the “Purging API” tab on your service’s dashboard.

In many cases, you don’t need to manually purge because of the Automatic Cache Invalidation via Mutations supported by Stellate.

API Endpoint

The purging API for your service is available at https://admin.stellate.co/<service-name>.

Authentication

To use the Purging API you need to create and authenticate via a Purging API Token. You can create those tokens on your service’s dashboard via the Purging API Tokens section under the Settings tab.

If you have used the Purging API Playground on the dashboard, you will already see some tokens named similarly as dashboard-74asd8. This is nothing to worry about, as we automatically create tokens for you when you access the Purging API Playground.

If you use the Purging API programmatically, you will need to include the token in the stellate-token (or graphcdn-token) header. See below for an example implementation in Node.js

purge-all-posts.js
const fetch = require('node-fetch')
 
async function purgeAllPosts() {
  await fetch('https://admin.stellate.co/little-frog', {
    // Always use POST for purge mutations
    method: 'POST',
    headers: {
      // and specify the Content-Type
      'Content-Type': 'application/json',
      'stellate-token': 'das09dja09sjda0s9ja...',
    },
    body: JSON.stringify({ query: `mutation { purgePost }` }),
  })
}
 
purgeAllPosts().catch((e) => console.error(e))

Soft purging

By default, any data you purge via the Purging API is removed from the cache immediately. If you would like to mark the data as stale and have your stale-while-revalidate (or swr) rules kick in, you can instead soft purge those documents.

To do so, pass the soft: true argument to any of the available mutations.

mutation {
  purgeUser(id: [5], soft: true)
}

It is preferable to purge as fine-grained as possible. The less data you invalidate the higher your cache hit rate will be.

Schemaless Mutations

The Purging API provides some mutations by default. Those are available for you to use whether you synced your schema with Stellate or not. If you sync your schema with Stellate, we also offer a set of custom-built mutations based on your schema, which simplifies the integration a bit.

Purge a specific type

If you want to purge an arbitrary type, optionally limited by specific key fields you can pass it in as an argument.

The name of the _purgeType and similar mutations starts with an underscore, as we don’t want this generic name to conflict with your specific types.

type Mutation {
  _purgeType(type: String!, keyFields: [KeyFieldInput!], soft: Boolean): Boolean
}
 
input KeyFieldInput {
  name: String!
  value: String!
}

For example to either purge all Todos, or to purge Todos identified by the key field id with value 42 run the following mutations:

# purge all cached documents containing Todo's
mutation {
	_purgeType(type: "Todo")
}
 
# purge specific instances
mutation {
	_purgeType(type: "Todo", keyFields: [{name: "id", value: "42"}]
}

Purge via an operation name

With this mutation, you can purge all cached results of the query with the operation name(s) you provide.

type Mutation {
  _purgeOperationName(names: [String!]!, soft: Boolean): Boolean
}

For example, to invalidate all results of queries named listUsers and listTodos[:

mutation {
  _purgeOperationName(names: ["listUsers", "listTodos"])
}

Purge query root fields by name

Purge all queries containing a specific field at the root level.

There is s similarly named _purgeQueryField mutation, which extends the use of this mutation. While _purgeQuery will purge results whether or not arguments were passed in the original query, _purgeQueryField allows you to filter which documents will get purged based on those arguments.

type Mutation {
  _purgeQuery(queries: [String!]!, soft: Boolean): Boolean
}

Example:

mutation {
  _purgeQuery(queries: ["package"])
}

Purge query root fields by name and argument

type Mutation {
  _purgeQueryField(fields: [QueryFieldInput!]!, soft: Boolean): Boolean
}
 
input QueryFieldInput {
  name: String!
  args: _ArgumentsJSONObject
}
 
scalar _ArgumentsJSONObject

This is similar to the _purgeQuery mutation, however it 1) allows you to specify filters for which documents to purge based on arguments passed in the original query and 2) allows you to also purge queries where no arguments where passed.

For example, if you have the following query asking for a specific package

{
  package(name: "@urql/core") {
    __typname
    name
  }
}

you could then purge that result via the following mutation

mutation {
  _purgeQueryField(fields: [{ name: "package", args: { name: "@urql/core" } }])
}

Please note that arguments passed to the invalidation mutation need to match exactly the arguments passed to the original query. Partial matches are not supported at this time.

If you wanted to only purge results from the cache where no argument was passed, you could use the following mutation. This would not remove the result cached by our earlier sample query.

mutation {
  _purgeQueryField(fields: [{ name: "package" }])
}

Purge the cache for a scope

You can purge the cache for regular scopes as well as JWT-Scopes every time we encounter a scope we’ll create a surrogate key for it.

For regular scopes what we need from you is the following:

  1. The name of the scope and the arguments for that scope
  2. The arguments here are the names of the header/cookie along with its value.

The following example will purge the AUTHENTICATED scope where we saw a value of “bearer x” for the authorization header and a value of en-us for the locale header.

stellate.ts
const stellate = {
  config: {
    scopes: { AUTHENTICATED: 'header:authorization|header:locale' },
  },
}

Purge:

mutation {
  _purgeScope(
    scopeName: "AUTHENTICATED"
    scopeArguments: [
      { name: "authorization", value: "bearer x" }
      { name: "locale", value: "en-us" }
    ]
  )
}

For a JWT-based scope all we need from you is the name of the scope alongside the value of the claim that you want to purge. Here we’ll purge the cache for the JWT-Scope where we derived “Tom” as a value for the targeted attribute.

stellate.ts
const stellate = {
  config: {
    scopes: {
      AUTHENTICATED: {
        definition: 'header:authorization',
        jwt: {
          claim: 'sub',
          algorithm: 'HS256',
          secret: ':a_very_secret_passphrase',
        },
      },
    },
  },
}
mutation {
  _purgeJwtScope(scopeName: "AUTHENTICATED", scopeValue: "Tom")
}

Purge the complete cache

You can purge all cached results Stellate has stored with the special _purgeAll mutation. Be extra careful when using this, as it will cause a traffic spike to your origin server.

⚠️

Purging all queries will temporarily increase traffic to your origin server while we don’t have anything cached anymore. Use this sparingly as a last resort and make sure your origin servers can handle the resulting traffic spike.

mutation {
  _purgeAll
}

Additional Mutations Available with Schema Sync Enabled

Once you sync your schema with Stellate, additional mutations based on your schema will be available via the Purging API as well.

Purging Specific Types

In addition to the _purgeType mutation, you will also see more specific mutations to purge cached documents containing specific types.

type Mutation {
	purge$Type(
		id: [String!],
		soft: Boolean
	): Boolean
}

If your schema has a Package type, for example, you could run the following mutation to purge all documents containing it:

mutation {
  purgePackage
}

or this mutation to purge documents containing a specific package (assuming name was defined as a key field)

mutation {
  purgePackage(name: "@urql/core")
}

Purging Specific Query Root Fields

Similar to types, we generate more specific mutations for known query root fields.

type Mutation {
	purgeQuery_$Field(
		args: [_ArgumentsJSONObject]!,
		soft: Boolean
	): Boolean
}
 
scalar _ArgumentsJSONObject

Using our package example from earlier, you could rewrite that mutation as follows, as long as Stellate knows about your schema:

mutation {
  purgeQuery_package(args: { name: "@urql/core" })
}

Additional API Changes with Schema Sync Enabled

⚠️

In addition to the above mutations, if you sync your schema with Stellate there are a couple of additional changes to the Purging API detailed below.

_purgeQuery and _purgeQueryField make use of a new _QueryEnum, which is built based on all the possible field names on the Query root type. Their definition changes as follows:

type Mutation {
  _purgeQuery(queries: [_QueryEnum!]!, soft: Boolean): Boolean
 
  _purgeQueryField(fields: [QueryFieldInput!]!, soft: Boolean): Boolean
}
 
input QueryFieldInput {
  name: _QueryEnum!
  args: _ArgumentsJSONObject
}
 
scalar _ArgumentsJSONObject
 
# All possible field names on the Query root type
enum _QueryEnum {
  package
}

Which requires us to also update our sample purging mutations as follows:

mutation {
  _purgeQuery(queries: [package])
}
 
mutation {
  _purgeQueryField(fields: [{ name: package, args: { name: "@urql/core" } }])
}

If you have any questions or are unsure of how to use the Purging API, do not hesitate to reach out to our support team. You can use the in-app messenger available on the dashboard, or email support@stellate.co.

Last updated on