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
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 Todo
s, or to purge Todo
s 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:
- The name of the scope and the arguments for that scope
- 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.
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.
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.