Nhảy tới nội dung

Virtual

Lưu ý sau khi phiên bản KeystoneJS 5 chuyển sang chế độ duy trì để ra mắt phiên bản mới hơn. Chúng tôi đã dựa trên mã nguồn cũ này để phát triển một phiên bản khác với một số tính năng theo hướng microservices.

The Virtual field type allows you to define a read-only field which you define the resolver for. This can be used to return computed values, values combining multiple fields, or custom formated values. The resolver function used in the Virtual field type is an apollo server resolver, and supports the same arguments.

Usage

The most basic usage is to provide a resolver function which returns a String value. The first argument to the resolver function is the list item.

Basic

const { Virtual, Text } = require('@ocop/fields');

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

Return type

If the return type is not String then you need to define graphQLReturnType.

const { Virtual } = require("@ocopjs/fields");

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

Complex return types

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:

const { Virtual } = require("@ocopjs/fields");

ocop.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 }));
},
},
},
});

Field arguments

The GraphQL arguments to a Virtual field can be specified using the args option, which takes a list of { name, type } values. The values for these arguments are made available in the second argument to the resolver function.

const { Virtual, CalendarDay } = require("@ocopjs/fields");
const { format, parseISO } = require("date-fns");

ocop.createList("Example", {
fields: {
date: { type: CalendarDay },
formattedDate: {
type: Virtual,
resolver: (item, { formatAs = "do MMMM, yyyy" }) =>
item.date && format(parseISO(item.date), formatAs),
args: [{ name: "formatAs", type: "String" }],
},
},
});

Server-side queries

The item argument to the resolver function is the raw database representation of the item, so related items will not be directly available on this object. If you need to access data beyond what lives on the item you can execute a server-side GraphQL query using context.executeGraphQL().

const { Virtual, CalendarDay } = require('@ocop/fields');
const { format, parseISO } = require('date-fns');

ocop.createList('Example', {
fields: {
virtual: {
type: Virtual,
resolver: async (item, args, context) => {
const { data, errors } = await context.executeGraphQL({ query: `{ ... }` })
...
}
},
},
});

Config

OptionTypeDefaultDescription
resolverFunctionasync (item, args, context, info)
graphQLReturnTypeStringStringA GraphQL Type String
graphQLReturnFragmentString''A GraphQL Fragment String - Used by the Admin UI and required if using a nested graphQLReturnType.
extendGraphQLTypesArray[]An array of custom GraphQL type definitions
argsArray[]An array of { name, type } indicating the supported arguments for the field