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

Switch with associated data instead of constructor methods for partials

Open ermik opened this issue 4 years ago • 9 comments

This is a feature request.

Current implementation

Given a Node interface type and A, B, and C types that conform to it, it the following schema:

interface Node {
    id: ID!
}

type A implements Node {
    id: ID!
    name: String
}

# ... etc

type Query {
    node: Node
}

the code generator for the following query


query NodeQuery {
    node {
        id
        ... on A {
             name
        }
    }
}

would generate code that has asA getter producing an optional of A swift type.

This means for N types, we have to write N if let valueA = data.node.asA clauses.

Proposal

Generate an enum for Node type that has all of the type's known implementors as cases.

enum Node {
    case A(data: StructA)
    case B(data: StructB)
    // etc...
}

which would allow for a simpler access of the interface values using a switch, while still allowing if ... else syntax using if case let.

ermik avatar Jun 15 '20 14:06 ermik

It's a little hard to do it with the associated types since each type is different per query to make sure you're only trying to use the specific type requested in that query. However, I am working on something similar in this PR for the Swift Codegen project that will at least let you switch on the __typename.

designatednerd avatar Jun 15 '20 18:06 designatednerd

You're right. I have overlooked the query-tie-in! in context of a query, the interface types remain a switch-able condition. It's just that Node type wouldn't be global:

struct NodeQuery {
    enum Node {
        case A(data: NodeQuery.StructA)
    }
}

and its cases would follow the same definition logic currently used for the asType getters.

__typename addition sounds like fun and I can't wait to use it!

ermik avatar Jun 18 '20 19:06 ermik

I do see how the Node type appearing in different branches of the query would produce a different struct type in the associated value signature. Took me a second to get there. You're right.

ermik avatar Jun 18 '20 19:06 ermik

🤔 I'm gonna do some noodling on this and see what might be doable - I like where you're going with it though.

designatednerd avatar Jun 18 '20 21:06 designatednerd

@designatednerd any updates on this? Not being able to exhaustively switch over union types adds a fair amount of fragility that's hard to ignore.

solidcell avatar Mar 02 '22 22:03 solidcell

We are in progress on a full re-write of Codegen for a 1.0 release. I've got some notes around this in the proposal here. https://github.com/apollographql/apollo-ios/blob/release/1.0/CodegenProposal.md#concrete-subtypes-as-enums

AnthonyMDev avatar Mar 03 '22 21:03 AnthonyMDev

Hi 👋🏻 - we've taken this into consideration and decided to defer it to a future 1.x release. We're not rejecting nor closing this issue but it's not on the roadmap yet. If this issue is important to you please let us know in this issue and it will help with prioritization - thank you!

calvincestari avatar May 23 '22 21:05 calvincestari

@calvincestari Bump to this old issue, but is this still on a roadmap for 1.X? Would be super useful for something we're building.

mccarron avatar Mar 05 '24 20:03 mccarron

Hi @mccarron - it's still not on our current roadmap unfortunately. @AnthonyMDev and I will discuss it but at this point it's unlikely to be a 1.x feature.

calvincestari avatar Mar 05 '24 21:03 calvincestari