Skip to content

Using an Interface inline fragment inside of a Union is awkward to unpack #336

Open
@alex-torok

Description

@alex-torok

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions