Skip to content

Instantly share code, notes, and snippets.

@fbaiodias
Last active July 21, 2021 19:04
Show Gist options
  • Save fbaiodias/77406c29ddf37fe46c3c to your computer and use it in GitHub Desktop.
Save fbaiodias/77406c29ddf37fe46c3c to your computer and use it in GitHub Desktop.
GraphQL circular dependencies

Circular dependencies on GraphQL schemas

Problem

Whenever I uncomment the lines on author.js I get the following error:

/Users/xicombd/Code/taskq/taskq-api/node_modules/graphql/jsutils/invariant.js:20
    throw new Error(message);
    ^

Error: Can only create List of a GraphQLType but got: undefined.
    at invariant (/Users/xicombd/Code/taskq/taskq-api/node_modules/graphql/jsutils/invariant.js:20:11)
    at new GraphQLList (/Users/xicombd/Code/taskq/taskq-api/node_modules/graphql/type/definition.js:712:39)
    at Object.<anonymous> (/Users/xicombd/Code/taskq/taskq-api/lib/schema/types/author.js:21:13)
    at Module._compile (module.js:435:26)
    at normalLoader (/Users/xicombd/Code/taskq/taskq-api/node_modules/babel-core/lib/api/register/node.js:199:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/xicombd/Code/taskq/taskq-api/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at Object.<anonymous> (/Users/xicombd/Code/taskq/taskq-api/lib/schema/types/post.js:6:17)
    at Module._compile (module.js:435:26)
    at normalLoader (/Users/xicombd/Code/taskq/taskq-api/node_modules/babel-core/lib/api/register/node.js:199:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/xicombd/Code/taskq/taskq-api/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)

Any ideas on how to deal with this?

EDIT: Fix

Using a function to return the fields on author.js does the trick:

On author.js
@@ -13 +13 @@
-   fields: {
+   fields: () => ({
import {
GraphQLObjectType,
GraphQLID,
GraphQLString,
GraphQLNonNull,
// GraphQLList
} from 'graphql'
// import GraphQLPost from './post'
export default new GraphQLObjectType({
name: 'Author',
fields: {
id: {
type: new GraphQLNonNull(GraphQLID)
},
name: {
type: GraphQLString
},
// posts: {
// type: new GraphQLList(GraphQLPost),
// resolve (parent, args) {
// return [
// {
// id: 'foo',
// name: 'Foo',
// content: 'foo foo foo'
// },
// {
// id: 'bar',
// name: 'Bar',
// content: 'bar bar bar'
// }
// ]
// }
// }
}
})
import {
GraphQLObjectType,
GraphQLID,
GraphQLString,
GraphQLNonNull
} from 'graphql'
import GraphQLAuthor from './author'
export default new GraphQLObjectType({
name: 'Post',
fields: {
id: {
type: new GraphQLNonNull(GraphQLID)
},
title: {
type: GraphQLString
},
content: {
type: GraphQLString
},
author: {
type: GraphQLAuthor,
resolve (parent, args) {
return {
id: 'john',
name: 'John Doe'
}
}
}
}
})
import {
GraphQLSchema,
GraphQLObjectType,
GraphQLID,
GraphQLNonNull,
GraphQLList
} from 'graphql'
import GraphQLPost from './post'
import GraphQLAuthor from './author'
const Query = new GraphQLObjectType({
name: 'Query',
fields: () => ({
posts: {
type: new GraphQLList(GraphQLPost),
resolve (parent, args) {
return [
{
id: 'foo',
title: 'Foo',
content: 'foo foo foo'
},
{
id: 'bar',
title: 'Bar',
content: 'bar bar bar'
},
{
id: 'baz',
title: 'Baz',
content: 'baz baz baz'
}
]
}
},
post: {
type: GraphQLPost,
args: {
id: {
type: new GraphQLNonNull(GraphQLID)
}
},
resolve (parent, {id}) {
return {
id: 'foo',
title: 'Foo',
content: 'foo foo foo'
}
}
},
authors: {
type: new GraphQLList(GraphQLAuthor),
resolve (parent, args) {
return [
{
id: 'john',
name: 'John Doe'
},
{
id: 'jane',
name: 'Jane Doe'
}
]
}
},
author: {
type: GraphQLAuthor,
args: {
id: {
type: new GraphQLNonNull(GraphQLID)
}
},
resolve (parent, args) {
return {
id: 'john',
name: 'John Doe'
}
}
}
})
})
const Schema = new GraphQLSchema({
query: Query
})
export default Schema
@xpepermint
Copy link

Some important notes ... CommonJS modules export values, ES6 modules export immutable bindings. Use ES6 if possible to avoid problems.

@ebrentnelson
Copy link

Running into similar issue, but only when testing with jest. My graphql server runs just fine, but one of my tests fails with:

 Can only create List of a GraphQLType but got: undefined.

All of my fields values are functions so the solution must be different. I'm trying to figure out what jest is doing to things to make it blow up like this.

@fiibbb
Copy link

fiibbb commented Feb 28, 2017

Nice, this just saved me a couple hours.

@cotterjd
Copy link

cotterjd commented Oct 5, 2017

thank you so much for this solution.

@dakhipp
Copy link

dakhipp commented May 1, 2018

Thanks! You made my code cleaner!

In case it is helpful for anyone else, I used the package esm to enable starting my server with node -r esm server.js and nodemon -r esm server.js. Starting my server with that package allowed for ES6 import and export syntax while avoiding the step of compiling my server code with babel.

@ben-bradley
Copy link

Ya know that feeling when you've spent hours debugging a problem and discover that the fix is something super clean and easy.

🥇 to you, sir!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment