Skip to content
KeystoneJS LogoKeystoneJSv5

Virtual

Usage

If the resolver is a function that returns a string you don't need to define a return type.

keystone.createList('Example', {
  fields: {
    firstName: { type: Text },
    lastName: { type: Text },
    name: {
      type: Virtual,
      resolver: item => (`${item.firstName} ${item.lastName}`)
      };
    },
  },
});

If the return type is not a string define a graphQLReturnType.

keystone.createList('Example', {
  fields: {
    fortyTwo: {
      type: Virtual,
      graphQLReturnType: `Int`,
      resolver: () => 42,
    },
  },
});

For more complex types you can define a graphQLReturnFragment as well as extendGraphQLTypes. Resolver functions can be async so you can even fetch data from the file system or an external API:

keystone.createList('Example', {
  fields: {
    movies: {
      type: Virtual,
      extendGraphQLTypes: [`type Movie { title: String, rating: Int }`],
      graphQLReturnType: `[Movie]`,
      graphQLReturnFragment: `{
        title
        rating
      }`,
      resolver: async () => {
        const response = await fetch('http://example.com/api/movies/');
        const data = await response.json();
        return data.map(({ title, rating }) => ({ title, rating }));
      },
    },
  },
});

Config

OptionTypeDefaultDescription
resolverFunction(required)
graphQLReturnTypeString'String'A GraphQL Type String
graphQLReturnFragmentString''A GraphQL Fragment String -required for nested return types
extendGraphQLTypesArray[]An array of custom GraphQL type definitions

Have you found a mistake, something that is missing, or could be improved on this page? Please edit the Markdown file on GitHub and submit a PR with your changes.

Edit Page