Description
When using an interface to select common fields from multiple types in a Union query, I expected genqlient to define an interface type that I could use to access my fields. Instead, it generated interface types for each type in the union and gave me no easy method to access my common interface fields.
Example Schema:
type Query {
foo(): FooUnion
}
Union FooUnion: A | B | C
type A implements ColorInterface { ... }
type B implements ColorInterface { ... }
type C implements ColorInterface { ... }
interface ColorInterface {
color: String
relatedFoo: FooUnion
}
Example Query:
query query() {
foo() {
... on ColorInterface {
color
}
}
}
In this case, if I want to write code to pull the color value out, I need to type assert across A, B, and C (or write a Getter interface and insert a runtime check). This is a bit of a pain, but understandable
Unfortunately, the problem compounds itself when my FooUnion items contain links to other FooUnion items that I'd like to get the color for:
query query() {
foo() {
... on ColorInterface {
color
relatedFoo {
... on ColorInterface {
color
}
}
}
}
}
This creates a pretty awkward unpacking situation where I need to have a decent bit of nested boilerplate to access the fields in my query.
Describe the solution you'd like
It would be great if golang interface types were generated when performing an interface inline fragment on a union type.
In this case, it seems like a new interface type would need to be generated and applied to the QueryFooA
, QueryFooB
, and QueryFooC
types that were generated for the Union. I poked around in the generate/convert.go
code, but I didn't find an obvious place where a change to support this would be made.
This seems tricky to do, as the logic would need to know information about the interface inline fragment when generating the types for the union definition.
I'd consider working on this and opening a PR, but I'd like to hear from a maintainer to see how hard you think this would be (especially for someone who's never worked in the repo).
** Alternatives **
I don't have control over the schema, so changing the foo query to not return a union is not possible.
Using the shurcooL/graphql
library made this query trivial, as it was able to unmarshal the json directly into my query object. I'd prefer to have genqlient's type protections and schema validation on my query, but this particular usecase requires so much boilerplate as to not make it worth it.