Вы не можете ссылаться на существующий распознаватель внутри другого распознавателя. Единственный способ повторно использовать логику - это абстрагировать ее в отдельную функцию, которая вызывается обоими преобразователями. Например:
const getProcessedModelById = (id) => {
return getModelById(id).then(model => doSomeProcessing(model))
}
// model
resolve(parentValue, args) {
return getProcessedModelById(args.id)
}
// models
resolve(parentValue, args) {
return Promise.all(args.ids.map(id => getProcessedModelById(args.id)))
}
В зависимости от вида обработки, который вы выполняете на модели, это может быть возможно сделать через средства распознавания полей типа Model
. Допустим, ваш тип Model
имеет два поля - firstName
и lastName
, но ваша модель возвращает одно поле с именем name
. Ваш doSomeProcessing
просто берет это имя и разбивает его на firstName
и lastName
:
function doSomeProcessing (model) {
const names = model.name.split(' ')
return { firstName: names[0], lastName: names[1] }
}
Вместо этого ваши распознаватели могут просто вернуть все, что вернет getModelById
. Затем вы можете инкапсулировать логику «обработки» в определителе каждого поля:
// firstName field
resolve (parentValue) {
return parentValue.name.split(' ')[0]
}
// lastName field
resolve (parentValue) {
return parentValue.name.split(' ')[1]
}
Преимущество этого подхода в том, что «обработка» фактически не произойдет, если клиент не запросит это поле. В этом очень простом примере разрешение поля lastName
не дорого, но это не всегда так. Он также очень аккуратно инкапсулирует логику для полей, которые получены из нижележащего уровня данных. Тем не менее, он также может оказаться более дорогим (представьте, например, что вызов split
сам по себе был дорогим ... теперь мы вызываем этот метод дважды, а не один раз).