Ошибка типа схемы Graphql, указывающая на повторяющиеся типы, которых у нее нет?

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

У меня есть сервер, который захватывает мои папки с файлами '.graphql' и объединяет их в один большой, который я передаю вместе с моими преобразователями в 'makeExecutableSchema ()', как показано ниже.

        const folders      = fs.readdirSync(path.join(__dirname, './api'));
        const allResolvers = [];
        let typeDefs       = '';

        folders.forEach(folder => {
          if (folder !== 'directive') {
            typeDefs = typeDefs.concat(requireText(`./api/${folder}/${folder}.graphql`, require));
            const { resolver } = require(`./api/${folder}/${folder}.resolvers`);
            allResolvers.push(resolver);
          }
        });

        const resolvers = _.merge(allResolvers);
        return makeExecutableSchema({typeDefs, resolvers});

Теперь у меня постоянно вылетает ошибка

    Error: Schema must contain unique named types but contains multiple types named "Address".
        at invariant (C:\100hotwater\src\server\node_modules\graphql\jsutils\invariant.js:19:11)
        at typeMapReducer (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:216:58)
        at Array.reduce (<anonymous>)
        at C:\100hotwater\src\server\node_modules\graphql\type\schema.js:237:36
        at Array.forEach (<anonymous>)
        at typeMapReducer (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:232:51)
        at Array.reduce (<anonymous>)
        at new GraphQLSchema (C:\100hotwater\src\server\node_modules\graphql\type\schema.js:122:28)
        at Object.extendSchema (C:\100hotwater\src\server\node_modules\graphql\utilities\extendSchema.js:161:10)
        at buildSchemaFromTypeDefinitions (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:186:28)
        at _generateSchema (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:97:18)
        at Object.makeExecutableSchema (C:\100hotwater\src\server\node_modules\graphql-tools\dist\schemaGenerator.js:110:20)
        at Object.exports.allSchema (C:\100hotwater\src\server\helpers.js:22:28)
        at Server.graphQl (C:\100hotwater\src\server\index.js:28:34)
        at new Server (C:\100hotwater\src\server\index.js:17:14)
        at Object.<anonymous> (C:\100hotwater\src\server\index.js:42:19)

Эта схема определенно не содержит дубликатов, хотя, как видно ниже, она распечатана прямо перед вводом функции "makeExecutableSchema" () ".

      type Lead {
        _id: String
        owner: User
        address: Address
        steps: [Step]
      }

      type Mutation {
        createLead(
          owner: String!
          address: Address
          steps: [Step]
        ): Lead
      }

      type Address {
        lat: Int
        lng: Int
        formattedAddress: String
      }

      type Step {
        goto: String
        key: String
        str: String
      }

      type User {
        _id: String
        email: String
        firstName: String
        lastName: String
        mobile: Int
        phone: Int
        billingAddress: String
        password: String
        leads: [Lead]
      }

      type Query {
        signedInUser: User
        userByEmail(email: String!): User # @isAuthenticated
      }

      extend type Mutation {
        signIn(email: String!, password: String!): SignInResponse!
        createUser(
          email: String!
          firstName: String!
          lastName: String
          mobile: Int
          billingAddress: String
          password: String
        ): User
      }

      type SignInResponse {
        token: String
        refreshToken: String
      }

Я заметил, что в файле "node_modules \ graphql \ type \ schema.js: 216: 58" он, кажется, дважды перебирает типизацию и, очевидно, дважды улавливает адрес при проверке и отправляет сообщение об ошибке, но я все еще не уверен, куда идти отсюда. Такие простые ошибки, как эта в Graphql, делают его действительно трудным для любви.

Любая помощь приветствуется.

Исправление

Короче говоря, благодаря Дэну, приведенному ниже, я определял тип адреса и использовал его как для ввода (мутация), так и для вывода (запрос - вывод). В то время я не понимал, что вам нужно по-другому определять типы и входные данные. Рабочая схема .graphql ниже.

      type Lead {
        _id: String
        owner: User
        address: Address
        steps: [Step]
      }

      type Address {
        lat: Int
        lng: Int
        formattedAddress: String
      }

      type Mutation {
        createLead(
          owner: String!
          address: AddressInput 
          steps: [Step]
        ): Lead
      }

      input AddressInput {
        lat: Int
        lng: Int
        formattedAddress: String
      }
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
3
0
3 955
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не уверен, как выглядит один из ваших модулей распознавателя, но подозреваю, что вы хотели сделать что-то вроде этого:

const resolvers = _.merge(...allResolvers) // note the spread operator

В противном случае вызов merge на самом деле ничего не делает, и ваше свойство resolvers в конечном итоге становится массивом, а не объектом.

Обновлено: не заметил этого на первый взгляд, но вы используете типы в качестве входных данных. Если вы хотите использовать объект той же формы, что и тип Address, вы должны определить для него отдельный тип ввода:

type Address {
  lat: Int
  lng: Int
  formattedAddress: String
}

input AddressInput {
  lat: Int
  lng: Int
  formattedAddress: String
}

Типы не могут использоваться для входов, а входы не могут использоваться для типов. Если бы мы определяли схему программно, обычно мы бы увидели ошибку. Очевидно, создание схемы из SDL не приводит к такой же ошибке. Если вы добавите соответствующие типы ввода для Address и Step, ваша схема должна сгенерироваться правильно.

Спасибо, Дэниел, на самом деле это была проблема, которую мы только что исправили, но, к сожалению, проблема с несколькими типами все еще существует.

Ryann Galea 17.05.2018 01:07

@ 22Ryann Odd. У вас есть ссылка репо, которой вы могли бы поделиться? Трудно понять, что может быть не так, не глядя на основной код.

Daniel Rearden 17.05.2018 01:09

в src / server / src / helpers.ts

Ryann Galea 17.05.2018 01:17

Дэниел, спасибо, что нашли время. Сегодня вечером я еще раз посмотрю и поменяю файлы. На самом деле я возвращаюсь к некоторому другому коду, который у меня есть, где я использовал типы в другой ситуации, и, похоже, он работает явно неправильно. Я постараюсь и, возможно, опубликую его, чтобы попытаться понять, что вы думаете, если вы не против

Ryann Galea 17.05.2018 04:49

Получив это сейчас, Даниэль, пытаясь создать новый лид: «Тип Lead.address должен быть Output Type, но получено: AddressInput».

Ryann Galea 17.05.2018 12:41

Как подсказывает ошибка, вы не можете использовать входные данные там, где ожидается тип. У вас должны быть как тип для адреса, который будет использоваться для полей, так и Вход для адреса, который будет использоваться для аргументов.

Daniel Rearden 17.05.2018 13:30

Спасибо, Дэн, наконец-то понял контекст того, как правильно определять схему. Кажется немного странным, что вход и тип в основном идентичны. Наконец-то он заработал. Еще раз спасибо за время, которое вы здесь провели.

Ryann Galea 17.05.2018 13:51

Важно понимать, что, хотя в SDL они могут выглядеть одинаково, makeExecutableSchema превращает типы и входные данные в GraphQLObjectType и GraphQLInputObjectType соответственно, которые имеют разные свойства и используются по-разному. Например, только типы могут расширять интерфейсы, быть частью объединений или иметь аргументы в своих полях. Только входы могут иметь значения по умолчанию.

Daniel Rearden 17.05.2018 14:26

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