Типы объединения GraphQLServer «Абстрактный тип N должен преобразовываться в тип объекта во время выполнения» - PullRequest
0 голосов
/ 16 февраля 2020

Учитывая GraphQL union тип возвращаемого значения:

union GetBankAccountsResponseOrUserInputRequest = GetAccountsResponse | UserInputRequest

, предназначенный для возврата данным преобразователем:

type Query {
  getBankAccounts: GetBankAccountsResponseOrUserInputRequest!
}

Я получаю эти предупреждения или ошибки относительно __resolveType или __isTypeOf function:

Abstract type N must resolve to an Object type at runtime for field Query.getBankAccounts with value { ..., __isTypeOf: [function __isTypeOf] }, received "undefined". Either the N type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.'

Я искал несколько дней в вопросах github и SO, пытаясь устранить эту ошибку.

Реализация __resolveType или __isTypeOf в моих средствах распознавания не работает:

export const Query = {
  getBankAccounts: (parent, args, context: IContext, info) => {
    return {
      __isTypeOf(obj) { // OR __resolveType, none of them work
        return `GetAccountsResponse`;
      },
      accounts: []
    };
  },
};

Ответы [ 2 ]

0 голосов
/ 16 февраля 2020

Ваша карта преобразователя настроена неправильно.

Карта преобразователя, переданная в ApolloServer (или makeExecutableSchema), должна быть объектом, ключи которого являются именами типов в вашей схеме, при каждом сопоставлении ключей другому объекту, ключи которого являются именами полей этого типа. Затем каждое имя поля сопоставляется с функцией распознавателя.

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
  },
}

Вы используете ту же карту преобразователя, чтобы передать функцию resolveType для объединения или интерфейса. Шаблон такой же, но имя типа - это имя объединения или интерфейса, и вместо имени поля используется ключ __resolveType:

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
  },
  SomeUnion: {
    __resolveType: (parent) => { ... },
  }
}

Функция resolveType должна всегда вернуть строку, которая соответствует имени существующего типа объекта в вашей схеме.

Если вы используете __isTypeOf вместо __resolveType, то это будет выглядеть немного иначе, поскольку функция isTypeOf связана с конкретный тип объекта, а не интерфейс или объединение. Это все показано в документах . Таким образом, карта разрешения выглядит следующим образом:

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
    __isTypeOf: (parent) => { ... },
  },
}

__isTypeOf всегда должен возвращать либо true, либо false, в зависимости от того, является ли переданный объект на самом деле этим типом.

Вам нужно всего лишь использовать __resolveType или __isTypeOf. Если вы используете __isTypeOf, вы должны добавить его ко всем возможным типам объектов в объединении или интерфейсе.

0 голосов
/ 16 февраля 2020

Поскольку реализация __resolveType или __isTypeOf в моих преобразователях не работала для меня, я решил эту проблему, добавив __typename непосредственно в возвращаемый объект преобразователя.

В getBankAccounts реализация преобразователя:

async getBankAccounts(): GetBankAccountsResponseOrUserInputRequest {
    if (shouldGetUserInputRequest()) {
      return {
        __typename: "UserInputRequest",
        ...response,
      };
    }

    return {
      __typename: "GetAccountsResponse",
      accounts,
    };
  }

Надеюсь, что это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...