Skip to content
KeystoneJS LogoKeystoneJS

Creating lists

Keystone lists define your application's models. These models represent the entities of your application domain and map to the tables in your database.

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

Config

OptionTypeDefaultDescription
accessFunction | Object | BooleantrueAccess control options for the list.
adapterConfigObjectOverride the adapter config options for a specific list.
adminConfigObject{}Options for the AdminUI.
adminDocStringA description for the list used in the Admin UI.
cacheHintObject{}Configures a default caching hint for list.
fieldsObjectDefines the fields in a list.
hooksObject{}Functions to be called during list operations.
itemQueryNameStringChanges the item name in GraphQL queries and mutations.
labelStringlistNameOverrides label for the list in the AdminUI.
labelFieldStringnameSpecify a field to use as a label for individual list items.
labelResolverFunctionResolves labelField or idFunction to resolve labels for individual list items.
listQueryNameStringChanges the list name in GraphQL queries and mutations.
pathStringChanges the path in the Admin UI.
pluginsArray[]An array of plugins that can modify the list config.
pluralStringSpecify a plural for Keystone to use for the list.
queryLimitsObject{}Configures list-level query limits.
schemaDocStringA description for the list used in the GraphQL schema.
singularStringSpecify a singular noun for Keystone to use for the list.

Definitions

access

Access control options for the list.

Options for create, read, update and delete - can be a function, GraphQL where clause or Boolean. See the access control API documentation for more details.

adapterConfig

Override the adapter config options for a specific list. Normally adapterConfig is provided when initialising Keystone:

JS
const keystone = new Keystone({
  adapter: new Adapter({...}),
});

Specifying an adapter config on a list item will extend the default config for this list.

adminConfig

Options for the AdminUI including:

  • defaultPageSize
  • defaultColumns
  • defaultSort
  • maximumPageSize
JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
    email: { type: Text },
  },
  adminConfig: {
    defaultColumns: 'name,email',
    defaultPageSize: 50,
    defaultSort: 'email',
    maximumPageSize: 100,
  },
});

adminDoc

A description for the list used in the Admin UI. To document the list in the GraphQL schema, see schemaDoc;

JS
keystone.createList('Todo', {
  adminDoc: 'A list of things which need to be done.',
});

cacheHint

HTTP cache hint configuration for list. (See Apollo docs and HTTP spec.)

  • scope: 'PUBLIC' or 'PRIVATE' (corresponds to public and private Cache-Control directives)
  • maxAge: maximum age (in seconds) that the result should be cacheable for

Cache headers need to be enabled in the GraphQLApp instance:

JS
const app = new GraphQLApp({
  apollo: {
    tracing: true,
    cacheControl: {
      defaultMaxAge: 3600,
    },
  },
});

See also the Apollo cache control doc.

PRIVATE is a recommendation that browsers should cache the result, but forbids intermediate caches (like CDNs or corporate proxies) from storing it. It needs to be used whenever the result depends on the logged in user (including secrets and user-specific content like profile information). If the result could be different when a user logs in, PRIVATE should still be used even if no user is logged in.

JS
keystone.createList('Post', {
  fields: {
    title: { type: Text },
  },
  cacheHint: {
    scope: 'PUBLIC',
    maxAge: 3600,
  },
});

Cache hints can be dynamically returned from a function that takes an object with these members:

  • results: an array of query results
  • operationName: the name of the GraphQL operation that generated the results
  • meta: boolean value that's true for a meta (count) query
JS
keystone.createList('Post', {
  fields: {
    title: { type: Text },
  },
  cacheHint: ({ meta }) => {
    if (meta) {
      return {
        scope: 'PUBLIC',
        maxAge: 3600,
      };
    } else {
      return {
        scope: 'PRIVATE',
        maxAge: 60,
      };
    }
  },
});

fields

Defines the fields to use in a list.

JS
keystone.createList('Post', {
  fields: {
    title: { type: Text },
  },
});

See: Fields for more information on configuring field options.

hooks

Specify functions to be executed during list operations. Supported hooks include:

  • Create and update operations
    • resolveInput
    • validateInput
    • beforeChange
    • afterChange
  • Delete operations
    • validateDelete
    • beforeDelete
    • afterDelete

See List Hooks in the API docs and the Hooks Guide for details.

Usage

JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
  },
  hooks: {
    resolveInput: ({ resolvedData }) => {
      return {
        name: `${resolvedData.name} the Great!`,
      };
    },
  },
});

itemQueryName

Changes the item name in GraphQL queries and mutations.

JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
  },
  itemQueryName: 'Person',
});

With the above example a GraphQL query might look like this:

GraphQL
query {
  Person(where: { id: "1" }) {
    name
  }
}

label

Overrides label for the list in the AdminUI. Default is listName.

labelField

Specify a field to use as a label for individual list items.

JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
    email: { type: Text },
  },
  labelField: 'name',
});

labelResolver

Function to resolve labels for individual list item. Default resolves the labelField.

JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
    email: { type: Text },
  },
  labelResolver: item => `${item.name} - ${item.email}`,
});

listQueryName

Changes the list name in GraphQL queries and mutations.

JS
keystone.createList('User', {
  fields: {
    name: { type: Text },
  },
  listQueryName: 'People',
});

With the above example a GraphQL query might look like this:

GraphQL
query {
  allPeople {
    name
  }
}

path

Changes the path in the Admin UI. Updating plural and singular values will not change the route in the admin UI. You can specify this using path.

plugins

An array of functions that modify config values. Plugin functions receive (config, { listKey, keystone }), where config is the a list config object, listKey is the name of the list, and keystone is the keystone object. They should return a valid list config. Plugin functions are executed in the order provided in the list, with the output config of one being passed as input to the next. The output of the final plugin is used to construct the List instance.

JS
const setupUserList = ({ fields, ...config }) => {
  return {
    ...config,
    fields: {
      ...fields,
      name: { type: Text },
      password: { type: Password },
    },
  };
};

keystone.createList('User', {
  plugin: [setupUserList],
});

This provides a method for packaging features that can be applied to multiple lists.

plural

Keystone will attempt to determine a plural for list items. Sometimes Keystone will not be able to determine the plural forcing you to change the list name. Or sometimes Keystone may get it wrong, especially for non-English words.

E.g. Keystone thinks the correct plural for Octopus is "Octopi". Everyone knows the scientifically accurate plural is "Octopodes":

JS
keystone.createList('Octopus', {
  fields: {
    legs: { type: Integer },
  },
  plural: 'Octopodes',
});

queryLimits

Configuration for limiting the kinds of queries that can be made against the list, to avoid queries that might overload the server.

See also global query limits on the Keystone object.

  • maxResults: maximum number of results that can be returned in a query (or subquery)
JS
keystone.createList('Post', {
  fields: {
    title: { type: Text },
  },
  queryLimits: {
    maxResults: 100,
  },
});

schemaDoc

A description for the list used in the GraphQL schema. To document the list in the Admin UI, see adminDoc;

JS
keystone.createList('Todo', {
  schemaDoc: 'A list of things which need to be done.',
});

singular

Keystone list names should be singular and Keystone will attempt to determine a plural.

Where Keystone can't determine a plural you may be forced to use a different list name.

The singular option allows you to change the display label for singular items.

E.g. Keystone can't determine a plural for 'Sheep'. Let's change the singular option:

JS
keystone.createList('WoolyBoi', {
  fields: {
    sheepName: { type: Text },
  },
  singular: 'Sheep',
  plural: 'Sheep',
});

Note: This will override labels in the AdminUI but will not change graphQL queries. For queries and mutations see: itemQueryName and listQueryName.

On this page

Edit on GitHub