Graphql: полностью изменить тип поля в схеме - PullRequest
0 голосов
/ 25 июня 2018

Мне нужно полностью изменить тип поля.

Ситуация: у меня есть шлюз, который объединяет несколько служб.Он извлекает их схемы с помощью самоанализа, преобразует их, добавляя пространства имен к типам (с помощью apollo graphql-tools) и помещая их во вложенные запросы (например, Query: { ServiceName: { serviceQuery } }), создавая новую схему с типами ServiceNameQuery и устанавливая преобразователи delegate.После этого мне нужно создать кросс-сервисные ссылки.

У меня есть ServiceA, который имеет тип со свойством related, который содержит идентификатор от TargetType от ServiceB.Мне нужно изменить тип свойства related с ID на TargetType и добавить распознаватель, который будет извлекать данные из ServiceB.

Вот реальный пример: enter image description here

Для этого я запускаю 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;
    },
  });

Я продолжаю получать эту ошибку, и преобразователь не запускается,Если я таким же образом добавляю новое поле с другим именем - это работает.Но если имя одинаковое - ошибка

1 Ответ

0 голосов
/ 27 июня 2018

Хорошо, я понял.Сшитая схема отслеживает основные сшитые схемы.Изменение типа в схеме верхнего уровня не влияет на него, поэтому приводит к внутреннему конфликту типов.Поэтому тип должен быть изменен ДО объединения

...