Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typechecking loop error with circular node reference #258

Closed
tobyjsullivan opened this issue Nov 19, 2017 · 5 comments
Closed

typechecking loop error with circular node reference #258

tobyjsullivan opened this issue Nov 19, 2017 · 5 comments

Comments

@tobyjsullivan
Copy link

I'm hitting a wall while trying to build an API with circular references between types.

A simplified example of my types looks like this:

Role {
  Company
  Employee
}
Employee {
  roles List(Role)
}

Attempting to create this results in a typechecking loop error from the go compiler.

This seems to be a result of the employeeType referencing roleType which in turn references employeeType again.

I would expect these kinds of models to be central to a Graph API. Is there a better way to be building this?

Thanks for any feedback.

@jmalloc
Copy link

jmalloc commented Nov 21, 2017

Looks like "field thunks" are the way to do this. The graphql.ObjectConfig.Fields field can be a function which is evaluated lazily, rather than a map[string]Field.

Using field thunks along with moving the definition into an init() function seems to do the trick.

var SomeType graphql.Type

func init() {
	SomeType = graphql.NewObject(graphql.ObjectConfig{
		Name: "SomeType",
		Fields: func() graphql.Fields { // notice func here
			return graphql.Fields{
				"circularRef": {
					Type: Environment,
				},
			}
		},
	})
}

Update: I may have spoken too soon, I'm now getting a runtime error:

fields must be an object with field names as keys or a function which return such an object

@jmalloc
Copy link

jmalloc commented Nov 21, 2017

Ok, the issue is because a type-switch is being used to identify whether a thunk is being used, and my closure was not statically typed as FieldsThunk, the correct example is:

var SomeType graphql.Type

func init() {
	SomeType = graphql.NewObject(graphql.ObjectConfig{
		Name: "SomeType",
		Fields: graphql.FieldsThunk(func() graphql.Fields { // notice func here
			return graphql.Fields{
				"circularRef": {
					Type: Environment,
				},
			}
		}),
	})
}

@tobyjsullivan
Copy link
Author

You're a lifesaver, mate! Thank you. Closing the issue as this solution resolved it.

@bbuck
Copy link
Collaborator

bbuck commented Nov 28, 2017

As a side note, another way to do this is with Object.addFieldConfig. I've always done it this way in the past, creating partial types for each and then adding the circular fields afterwards.

@SasukeBo
Copy link

there is a problem with FieldThunk and AddFieldConfig, if your object's fields returned by FieldThunk, you can't dynamically add field into your object by AddFieldConfig. I ran into this problem because I restruct my project's fields/types/schema module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants