Graphql: Circular references causes compiler error

Created on 11 Oct 2016  路  4Comments  路  Source: graphql-go/graphql

When defining GraphQL types where two types reference each other, this causes compiler error when building:

typechecking loop involving showType = graphql.NewObject(graphql.ObjectConfig literal)

Here's the GraphQL types that I have defined where it references each other:

var showType = graphql.NewObject( graphql.ObjectConfig{ Name: "Show", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.String, }, "episodes": &graphql.Field{ Type: graphql.NewList(episodeType), } } } )

var episodeType = graphql.NewObject( graphql.ObjectConfig{ Name: "Episode", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.String, }, "show": &graphql.Field{ Type: showType, } } )

Are there any workarounds for this issue?

question

Most helpful comment

@rubberviscous I also had this problem once. My solution was dynamically adding one of the problematic fields inside init(), It's not really pretty but it seems work at least

package main

import (
    "github.com/graphql-go/graphql"
)

var showType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Show",
    Fields: graphql.Fields{
        "id":       &graphql.Field{Type: graphql.String},
        "episodes": &graphql.Field{Type: graphql.NewList(episodeType)},
    },
})

var episodeType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Episode",
    Fields: graphql.Fields{
        "id": &graphql.Field{Type: graphql.String},
    },
})

func init() {
    episodeType.AddFieldConfig("show", &graphql.Field{Type: showType})
}

All 4 comments

@rubberviscous I also had this problem once. My solution was dynamically adding one of the problematic fields inside init(), It's not really pretty but it seems work at least

package main

import (
    "github.com/graphql-go/graphql"
)

var showType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Show",
    Fields: graphql.Fields{
        "id":       &graphql.Field{Type: graphql.String},
        "episodes": &graphql.Field{Type: graphql.NewList(episodeType)},
    },
})

var episodeType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Episode",
    Fields: graphql.Fields{
        "id": &graphql.Field{Type: graphql.String},
    },
})

func init() {
    episodeType.AddFieldConfig("show", &graphql.Field{Type: showType})
}

@sfriedel That worked! Many thanks!

Hi @rubberviscous, thanks a lot for reaching us for a question, also the solution @sfriedel wrote above is the go-to one, closing this one, thanks guys!

I have the same issue here, but for InputObject. I tried the same workaround, but there is no AddFieldConfig defined for InputObject. I've done the following hack but I'm worried about it being broken in a subsequent commit:

func init() {
    // this is a bit hacky. there is no AddFieldConfig() equivalent for input types so we need to force
    // the input field mapping initialization, and then directly assign the new field
    GraphQLInputType.Fields()

    GraphQLInputType.Fields()["children"] = &graphql.InputObjectField{
        PrivateName: "children",
        Type: graphql.NewList(GraphQLInputType),
    }
}

Any other suggestions?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yookoala picture yookoala  路  4Comments

sanae10001 picture sanae10001  路  5Comments

titanous picture titanous  路  3Comments

amedeiros picture amedeiros  路  3Comments

januszm picture januszm  路  6Comments