Я пытаюсь сделать мою схему GraphQL компонуемой с помощью схема сшивания, но я борюсь с тем, как разрешить свойства типов из другой части.
Вот схема перед разложением:
type Referee {
id: ID!
stringProp: String!
}
type Referer {
id: ID!
pointer: Referee!
}
type Query {
referers: [Referer]
}
Оба типа имеют преобразователи в соответствующих схемах, которые расширяют объект { id } в { id, stringProp } или { id, pointer: { id } }, так что запрос
query FromSingleSchema {
referers: {
id
pointer {
id
stringProp
}
}
}
разрешается, как ожидалось; Query.referers преобразуется в список объектов [{id}], и каждый из них, в свою очередь, сначала разрешается в Referer, а затем извлекает указанный Referee через преобразователи типов.
Теперь я пытаюсь разложить схему:
// schema A
type Referee {
id: ID!
stringProp: String!
}
// schema B
type Referer {
id: ID!
}
type Query {
referers: [Referer]
}
// schema Extensions
extend type Referer {
pointer: Referee!
}
и снова составим:
// both schemaA and schemaB have been created with makeExecutableSchema
import schemaA from './A'
import schemaB from './B'
// schemaExtensions is just a raw GraphQL string
// resolverExtensions is shown below
import { schemaExtensions, resolverExtensions } from './B'
const schema = mergeSchemas({
schemas: [schemaA, schemaB, schemaExtensions],
resolvers: Object.assign({}, resolverExtensions)
})
// resolverExtensions defined as follows:
{
Referer: {
pointer: {
fragment: 'fragment IdFragment on Referee { id }',
resolve: o => ({ id: o.pointerId })
}
}
}
Благодаря этому я могу без проблем выполнить этот запрос:
query OnlyIdFromDecomposedSchemas {
referers: {
id
pointer {
id
}
}
}
но это не удается
query FullRefereeFromDecomposedSchemas {
referers: {
id
pointer {
id
stringProp
}
}
}
с сообщением об ошибке
Cannot return null for non-nullable field Referee.stringProp.
Что мне нужно сделать, чтобы преобразователь типов для Referee смог заполнить остальные свойства после того, как { id } станет доступным, как это происходит в единой неразложенной схеме?


Думаю, вы ищете делегирование схемы. Делегирование схемы - это способ автоматической пересылки запроса (или части запроса) из родительской схемы в другую схему (называемую подсхемой), которая может выполнить запрос.
Вы можете использовать такой метод delegateToSchema в своем преобразователе:
{
Referer: {
pointer : {
resolve(parent, args, context, info) {
return info.mergeInfo.delegateToSchema({
schema: schemaA,
operation: 'query',
fieldName: 'referee', // modify according to your query for referee
context,
info,
});
}
}
}
}
Я считаю, что проблема здесь в том, как ваш текущий resolverExtension реализует стрелочную функцию resolve. На самом деле делегирование схемы здесь необходимо - мне было бы интересно, как ваши существующие преобразователи уже знали, как вернуть запрошенное поле pointer и его подполя. В вашей стрелочной функции вы путаете Referer (родительский, передается вашей стрелочной функции) с Referee. Используйте здесь другое имя аргумента, вместо o это должно быть referer. И затем вы либо используете delegateToSchema, либо у вас есть простой бэкэнд, который вы можете вызвать на место и попросить pointer / Referee.
Я читал об этом, но, похоже, это требует, чтобы я делегировал операцию
queryв другой схеме - в настоящее время у меня ее нет, и я бы не хотел создавать ее только из-за этой необходимости. Могу ли я передать полномочия другой схеме, не выполняя там явную операцию запроса?