Я теперь полностью потратил свой вечер, пытаясь разобраться с этим, но не могу дать ответа, даже после нескольких поисков.
У меня есть сервер, который захватывает мои папки с файлами '.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
}






Я не уверен, как выглядит один из ваших модулей распознавателя, но подозреваю, что вы хотели сделать что-то вроде этого:
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, ваша схема должна сгенерироваться правильно.
@ 22Ryann Odd. У вас есть ссылка репо, которой вы могли бы поделиться? Трудно понять, что может быть не так, не глядя на основной код.
в src / server / src / helpers.ts
Дэниел, спасибо, что нашли время. Сегодня вечером я еще раз посмотрю и поменяю файлы. На самом деле я возвращаюсь к некоторому другому коду, который у меня есть, где я использовал типы в другой ситуации, и, похоже, он работает явно неправильно. Я постараюсь и, возможно, опубликую его, чтобы попытаться понять, что вы думаете, если вы не против
Получив это сейчас, Даниэль, пытаясь создать новый лид: «Тип Lead.address должен быть Output Type, но получено: AddressInput».
Как подсказывает ошибка, вы не можете использовать входные данные там, где ожидается тип. У вас должны быть как тип для адреса, который будет использоваться для полей, так и Вход для адреса, который будет использоваться для аргументов.
Спасибо, Дэн, наконец-то понял контекст того, как правильно определять схему. Кажется немного странным, что вход и тип в основном идентичны. Наконец-то он заработал. Еще раз спасибо за время, которое вы здесь провели.
Важно понимать, что, хотя в SDL они могут выглядеть одинаково, makeExecutableSchema превращает типы и входные данные в GraphQLObjectType и GraphQLInputObjectType соответственно, которые имеют разные свойства и используются по-разному. Например, только типы могут расширять интерфейсы, быть частью объединений или иметь аргументы в своих полях. Только входы могут иметь значения по умолчанию.
Спасибо, Дэниел, на самом деле это была проблема, которую мы только что исправили, но, к сожалению, проблема с несколькими типами все еще существует.