I have now completely wasted my evening trying to work this one out but am beyond an answer, even after multiple searches.
I have my server which grabs my folders of '.graphql' files and merges them into one large one which I pass along with my resolvers into 'makeExecutableSchema()' as seen below
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});
Now i am constantly getting an error
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)
This schema most definitely does not contain duplicates though as seen below of it printed out right before entering the "makeExecutableSchema"()" function.
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
}
I noticed in the file "node_modules\graphql\type\schema.js:216:58" it seems to loop through the typings twice and obviously catching the Address twice in the check and posting the error but i'm still unsure where to go from here. Simple errors like this in Graphql is making it really hard to love.
Any help is appreciated.
In short thanks to Dan below, I was defining the Address type and using it for both my Input (Mutation) and my Output (Query - Lead). What I didn't realise at the time was that you needed to define types & inputs differently. The working .graphql schema below.
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
}
I'm not sure what one of your resolver modules looks like, but I suspect you meant to do something like this:
const resolvers = _.merge(...allResolvers) // note the spread operator
Otherwise, calling merge
is not actually doing anything and your resolvers
property ends up being an array instead of an object.
EDIT: Didn't notice it on first glace, but you're using types as inputs. If you want to use an object with the same shape as the Address
type, you have to define a separate input type for it:
type Address {
lat: Int
lng: Int
formattedAddress: String
}
input AddressInput {
lat: Int
lng: Int
formattedAddress: String
}
Types cannot be used for inputs and inputs cannot be used for types. If we were defining the schema programatically, we'd normally see an error to that effect. Evidently generating the schema from SDL doesn't generate the same error. If you add the appropriate input types for Address and Step, your schema should generate correctly.