Мне нужно полностью изменить тип поля.
Ситуация: у меня есть шлюз, который объединяет несколько служб.Он извлекает их схемы с помощью самоанализа, преобразует их, добавляя пространства имен к типам (с помощью apollo graphql-tools) и помещая их во вложенные запросы (например, Query: { ServiceName: { serviceQuery } }
), создавая новую схему с типами ServiceNameQuery
и устанавливая преобразователи delegate
.После этого мне нужно создать кросс-сервисные ссылки.
У меня есть ServiceA
, который имеет тип со свойством related
, который содержит идентификатор от TargetType
от ServiceB
.Мне нужно изменить тип свойства related
с ID
на TargetType
и добавить распознаватель, который будет извлекать данные из ServiceB
.
Вот реальный пример:
Для этого я запускаю visitSchema
(из graphql-tools
преобразований) над объединенной схемой, найдите нужное мне поле, извлеките TargetType
из схемы, измените тип поля и установитераспознаватель, подобный следующему:
const targetType = schema.getType('TargetType');
field.type = targetType;
field.astNode.type = targetType.astNode;
field.resolve = (parent, args, ctx, info) => {
console.log(parent);
return null;
};
Когда я запускаю console.log, перед тем как передать его на сервер GraphQL, введите тип поверх результирующей схемы - я вижу, что его тип и astNode действительно изменились, и они соответствуют действительности.
Когда я запускаю самоанализ, я вижу, что тип поля является правильным.
Но когда я запускаю запрос наподобие query { ServiceA { serviceQuery { id related { id } } } }
, я получаю сообщение об ошибке на этапе анализа запроса:
Error: Field "related" must not have a selection since type "ID" has no subfields.
GraphQL request (5:19)
4: id
5: related {
^
6: id
at asErrorInstance (/.../node_modules/graphql/execution/execute.js:555:43)
at process._tickCallback (internal/process/next_tick.js:68:7)
Это событиене пытается вызвать serviceQuery
resolver.
Где он получает тип идентификатора этого поля, когда я изменил определение типа?Где еще мне нужно изменить его тип?
UPD Даже если я создаю новый тип, подобный этому:
schema = return visitSchema(schema, {
[VisitSchemaKind.OBJECT_TYPE](type: GraphQLObjectType) {
if (type.getFields().relatedNews) {
// console.log(type.getFields());
return new GraphQLObjectType({
name: type.name,
fields: {
...fromPairs(Object.values(type.getFields()).map(({name, type, args, resolve, description}) => [name, {type, args: {}, resolve, description}])),
relatedNews: {
type: schema.getType('NewsArticle'),
resolve(obj) {
console.log('foo');
}
}
}
});
}
return type;
},
});
Я продолжаю получать эту ошибку, и преобразователь не запускается,Если я таким же образом добавляю новое поле с другим именем - это работает.Но если имя одинаковое - ошибка