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
@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