apollo-ios icon indicating copy to clipboard operation
apollo-ios copied to clipboard

[Suggestion] Represent Union Types as an Enum instead of optionals

Open BrentMifsud opened this issue 1 year ago • 2 comments

Use case

For example.

Lets say I have:

union Person = Employee | Student

query PersonQuery {
    person {
        ... on Employee {
            // fields here
        }
        ... on Student {
           // fields here
        }
    }
}

when accessing the generated model, I have to do a bunch of unwrapping:

if let student = personQueryResponse.personQuery.person.asStudent {
    // do something for students
} else if let employee = personQueryResponse.personQuery.person.asEmployee {
  // do something for employees
} else {
    // what do we do here? The schema says person is non-optional, but none of the union types are populated.
}

This is extremely cumbersome to work with.

Describe the solution you'd like

Using my Person example above, it would be much nicer if we could work with union types as an enum instead.

switch personQueryResult.personQuery.person {
case let .student(student):
    // do something with student
case let .employee(employee):
    // do something with employee
case let .unknown(typeName):
   // this would be a scenario where the client has an out of date schema or the query did not request one of the available union types.
}

BrentMifsud avatar Oct 24 '23 23:10 BrentMifsud

This is something we've considered in the past. It's actually mentioned in the initial RFC I wrote for the new Codegen engine here.

I'm definitely not opposed to adding this feature. Generating this for every field that references a union may not always been helpful and could significantly increase generated code size. So I think I'd probably want to make it an opt-in feature on a per-selection-set-basis by default (maybe with an option to enable to across all operations as well).

I'm going to add this issue to our backlog of future feature additions, as is is something we would like to do eventually. Thanks for writing this up @BrentMifsud.

AnthonyMDev avatar Oct 25 '23 21:10 AnthonyMDev

Agreed that this is something that would be great to have, some closed-source implementations of GraphQL codegen I've worked with in the past modeled GraphQL unions as Swift enums with associated types and it was very ergonomic and nice to use compared with optional unwraps. One of the biggest benefits is that when you update your query or fragment to include a new possible type in a union, the compiler will ensure that you update all of your switch statements to accommodate it.

erichoracek avatar Mar 15 '24 22:03 erichoracek