graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Dangerous issue about Go anonymous composition

Open alimoli opened this issue 3 years ago • 1 comments

I discovered this bug trying to resolve this problem https://github.com/graphql-go/graphql/issues/183#issuecomment-659317404 .

Essentially, this library does not allow to have anonymous fields for compositions since those fields are not evaluated.

Example

type Car struct {
       Speed int `json:"speed"`
       Product
}

type Product struct {
       Price int `json:"price"`
       Description string `json:"description"`
}

GraphQL schema

carType := graphql.NewObject(graphql.ObjectConfig{
	Name: "Car",
	Fields: graphql.Fields{
		"speed": &graphql.Field{
			Type:        graphql.NewNonNull(graphql.Int),
		},
		"price": &graphql.Field{
			Type:        graphql.NewNonNull(graphql.Int),
		},
		"description": &graphql.Field{
			Type:        graphql.NewNonNull(graphql.String),
		},
	},
})

Result

The price and description fields has a null value for GraphQL library and this is not allowed since we declare a graphql.NewNonNull field. Indeed, we get the following error:

  • Cannot return null for non-nullable field price.
  • Cannot return null for non-nullable field description.

Temporary solution

The only way to fix this problem at the moment is to duplicate code:

type Car struct {
       Speed int `json:"speed"`
       Price int `json:"price"`
       Description string `json:"description"`
}

type Product struct {
       Price int `json:"price"`
       Description string `json:"description"`
}

Or changing a lot of things both internal and external (also the public fields to API consumers).

type Car struct {
       Speed int `json:"speed"`
       Product Product `json:"product"`
}

type Product struct {
       Price int `json:"price"`
       Description string `json:"description"`
}

Instead of:

{
   speed
   price
   description
}

We have to provide this:

{
   speed
   product {
      price
      description
   }
}

Both solutions are really limited and go against clean code.

alimoli avatar Jul 16 '20 13:07 alimoli

I found this as well the issue. In DefaultResolveFn the struct that's reflected isn't "flattened" so it' never accesses the tag on the struct field.

Nemesisesq avatar Aug 05 '20 03:08 Nemesisesq