Skip to content
KeystoneJS LogoKeystoneJS

Keystone class

Usage

JS
const { Keystone } = require('@keystonejs/keystone');

const keystone = new Keystone({
  /*...config */
});

Config

OptionTypeDefaultDescription
adapterObjectRequiredThe database storage adapter. See the Adapter framework docs for more details.
adaptersObjectundefinedA list of named database adapters. Use the format { name: adapterObject }.
appVersionObjectSee appVersionConfigure the application version and where it is made available.
cookieObjectSee: cookieCookie object used to configure the express-session middleware.
cookieSecretStringRequired in productionThe secret used to sign session ID cookies. Should be long and unguessable.
defaultAccessObjectundefinedDefault list, field, and custom schema access. See the Access control API docs for more details.
defaultAdapterStringundefinedThe name of the database adapter to use by default if multiple are provided.
nameStringundefinedThe name of the project. Appears in the Admin UI.
onConnectFunctionundefinedCallback that executes once keystone.connect() complete. Takes no arguments.
queryLimitsObject{}Configures global query limits
sessionStoreObjectundefinedA compatible Express session middleware.
schemaNamesArray['public']

appVersion

Configure the application version, which can be surfaced via HTTP headers or GraphQL

The version can be any string value you choose to use for your system. If addVersionToHttpHeaders is true then all requests will have the header X-Keystone-App-Version set. The version can also be queried from the GraphQL API as { appVersion }. You can control whether this is exposed in your schema using access, which can be either a boolean, or an object with schemaName keys and boolean values.

JS
const keystone = new Keystone({
  appVersion: {
    version: '1.0.0',
    addVersionToHttpHeaders: true,
    access: true,
  },
});

Why don't we just use access to control the HTTP header?

We want to attach the HTTP header at the very top of the middleware stack, so if something gets rejected we can at least be sure of the system version that did the rejecting. This happens well before we have worked out which schema the person is trying to access, and therefore our access control isn’t ready to be used. Also, the access control that we set up is all about controlling access to the GraphQL API, and HTTP headers are a Different Thing, so even if it was technically possible to use the same mechanism, it really makes sense to decouple those two things.

queryLimits

Configures global query limits.

These should be used together with list query limits.

JS
const keystone = new Keystone({
  queryLimits: {
    maxTotalResults: 1000,
  },
});
  • maxTotalResults: limit of the total results of all relationship subqueries

Note that maxTotalResults applies to the total results of all relationship queries separately, even if some are nested inside others.

Default: see Usage.

A description of the cookie properties is included in the express-session documentation.

secure

A secure cookie is only sent to the server with an encrypted request over the HTTPS protocol. If secure is set to true (as is the default with a production build) for a KeystoneJS project running on a non-HTTPS server (such as localhost), you will not be able to log in. In that case, be sure you set secure to false. This does not affect development builds since this value is already false.

You can read more about secure cookies on the MDN web docs.

Usage

JS
const keystone = new Keystone({
  /* ...config */
  cookie: {
    secure: process.env.NODE_ENV === 'production', // Default to true in production
    maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
    sameSite: false,
  },
});

cookieSecret

The secret used to sign session ID cookies. In production mode (process.env.NODE_ENV === 'production') this option is required. In development mode, if undefined, a random cookieSecret will be generated each time Keystone starts (this will cause sessions to be reset between restarts).

sessionStore

Sets the Express server's session middleware. This should be configured before deploying your app.

This example uses the connect-mongo middleware, but you can use any of the stores that work with express session.

JS
const expressSession = require('express-session');
const MongoStore = require('connect-mongo')(expressSession);

const keystone = new Keystone({
  sessionStore: new MongoStore({ url: 'mongodb://localhost/my-app' }),
});

Methods

MethodDescription
connectManually connect to Adapters.
createAuthStrategyCreates a new authentication middleware instance.
createItemsAdd items to a Keystone list.
createListAdd a list to the Keystone schema.
disconnectDisconnect from all adapters.
executeQueryRun GraphQL queries and mutations directly against a Keystone instance.
extendGraphQLSchemaExtend keystones generated schema with custom types, queries, and mutations.
prepareManually prepare Keystone middlewares.

connect()

Manually connect Keystone to the adapters. See Custom Server.

keystone.connect();

Note: keystone.connect() is only required for custom servers. Most example projects use the keystone start command to start a server and automatically connect.

createAuthStrategy(config)

Creates a new authentication middleware instance. See:

const authStrategy = keystone.createAuthStrategy({...});

createItems(items)

Allows bulk creation of items. This method's primary use is intended for migration scripts, or initial seeding of databases.

JS
keystone.createItems({
  User: [{ name: 'Ticiana' }, { name: 'Lauren' }],
  Post: [
    {
      title: 'Hello World',
      author: { where: { name: 'Ticiana' } },
    },
  ],
});

The author field of the Post list would have the following configuration:

JS
keystone.createList('Post', {
  fields: {
    author: { type: Relationship, ref: 'User' },
  },
});

Config

OptionTypeDescription
[listKey]ObjectAn object where keys are list keys, and values are an array of items to insert.

Note: The format of the data must match the lists and fields setup with keystone.createList()

It is possible to create relationships at insertion using the Keystone query syntax.

E.g. author: { where: { name: 'Ticiana' } }

Upon insertion, Keystone will resolve the { where: { name: 'Ticiana' } } query against the User list, ultimately setting the author field to the ID of the first User that is found.

Note an error is thrown if no items match the query.

createList(listKey, config)

Registers a new list with Keystone and returns a Keystone list object. See:

keystone.createList('Posts', {...});

Config

OptionTypeDefaultDescription
listKeyStringnullThe name of the list. This should be singular, E.g. 'User' not 'Users'.
configObject{}The list config. See the create list API docs for more details.

disconnect()

Disconnect all adapters.

executeQuery(queryString, config)

Use this method to execute queries or mutations directly against a Keystone instance.

Note: When querying or mutating via keystone.executeQuery, there are differences to keep in mind:

  • No access control checks are run (everything is set to () => true)
  • The context.req object is set to {} (you can override this if necessary, see options below)
  • Attempting to authenticate will throw errors (due to req being mocked)

Returns a Promise representing the result of the given query or mutation.

keystone.executeQuery('query-string', {...});

queryString

A GraphQL query string. For example:

GraphQL
query {
  allTodos {
    id
    name
  }
}

Can also be a mutation:

GraphQL
mutation newTodo($name: String) {
  createTodo(name: $name) {
    id
  }
}

Config

OptionTypeDefaultDescription
contextObject{}Override the default context object passed to the GraphQL engine. Useful for adding a req or setting the schemaName
variablesObject{}The variables passed to the graphql query for the given queryString.

extendGraphQLSchema(config)

Extends keystones generated schema with custom types, queries, and mutations.

JS
keystone.extendGraphQLSchema({
  types: [{ type: 'type MyType { original: Int, double: Float }' }],
  queries: [
    {
      schema: 'double(x: Int): MyType',
      resolver: (_, { x }) => ({ original: x, double: 2.0 * x }),
    },
  ],
  mutations: [
    {
      schema: 'triple(x: Int): Int',
      resolver: (_, { x }) => 3 * x,
    },
  ],
});

See the Custom schema guide for more information on utilizing custom schema.

Config

OptionTypeDescription
typesarrayA list of objects of the form { type, access } where the type string defines a GraphQL type.
queriesarrayA list of objects of the form { schema, resolver, access }.
mutationsarrayA list of objects of the form { schema, resolver, access }.
  • The schema for both queries and mutations should be a string defining the GraphQL schema element for the query/mutation, e.g.
JS
{
  schema: 'getBestPosts(author: ID!): [Post]',
}
  • The resolver for both queries and mutations should be a resolver function with following signature:
JS
{
  resolver: (parent, args, context, info, extra) => {},
}

For more information about the first four arguments, please see the Apollo docs. The last argument extra is an object that contains the following properties:

NameDescription
queryAn executable helper function for running a query.
accessAccess control information about the current user.
  • The access argument for types, queries, and mutations are all either boolean values which are used at schema generation time to include or exclude the item from the schema, or a function which must return boolean.
  • See the Access control API docs for more details.

prepare(config)

Manually prepare middlewares. Returns a promise representing the processed middlewares. They are available as an array through the middlewares property of the returned object.

Usage

JS
const { middlewares } = await keystone.prepare({
  apps,
  dev: process.env.NODE_ENV !== 'production',
});

Config

OptionTypedefaultDescription
appsArray[]An array of 'Apps' which are express middleware.
corsObject{ origin: true, credentials: true }CORS options passed to the cors npm module
devBooleanfalseSets the dev flag in Keystone' express middleware.
distDirStringdistThe build directory for keystone.
pinoOptionsObjectundefinedLogging options passed to the express-pino-logger npm module

On this page

Edit on GitHub