Сшивание схемы в Apollo GraphQL не разрешает типы из других частей

Я пытаюсь сделать мою схему 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 } станет доступным, как это происходит в единой неразложенной схеме?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
0
0
750
1

Ответы 1

Думаю, вы ищете делегирование схемы. Делегирование схемы - это способ автоматической пересылки запроса (или части запроса) из родительской схемы в другую схему (называемую подсхемой), которая может выполнить запрос.

Вы можете использовать такой метод 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,
          });
        }
      }
    }
  }

Я читал об этом, но, похоже, это требует, чтобы я делегировал операцию query в другой схеме - в настоящее время у меня ее нет, и я бы не хотел создавать ее только из-за этой необходимости. Могу ли я передать полномочия другой схеме, не выполняя там явную операцию запроса?

Tomas Aschan 03.05.2018 13:46

Я считаю, что проблема здесь в том, как ваш текущий resolverExtension реализует стрелочную функцию resolve. На самом деле делегирование схемы здесь необходимо - мне было бы интересно, как ваши существующие преобразователи уже знали, как вернуть запрошенное поле pointer и его подполя. В вашей стрелочной функции вы путаете Referer (родительский, передается вашей стрелочной функции) с Referee. Используйте здесь другое имя аргумента, вместо o это должно быть referer. И затем вы либо используете delegateToSchema, либо у вас есть простой бэкэнд, который вы можете вызвать на место и попросить pointer / Referee.

nether_cat 12.02.2019 09:18

Другие вопросы по теме