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.
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
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,
},
}
}),
})
}
You're a lifesaver, mate! Thank you. Closing the issue as this solution resolved it.
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.
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.
Most helpful comment
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: