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

Swift: Query containing fragment with same name as outer query field generates variables with wrong type

Open RobinDaugherty opened this issue 4 years ago • 1 comments

When generating Swift code for a query containing a fragment with the same field name as a field in the query.

fragment Gameplan on Gameplan {
  a b c
}
query TheThing {
  gameplan {
    ... Gameplan
  }
}

This is generated with --namespace Backend.

(Without a specified namespace, I don't believe there's a way that codegen would be able to generate code without this issue. This is because there's no "root namespace" in Swift.)

Intended outcome:

Backend.TheThingQuery.Data.Gameplan.Fragments type should contain a var of type Backend.Gameplan

public extension Backend {
    final class TheThingQuery: GraphQLQuery {
        public struct Data: GraphQLSelectionSet {
            public struct Gameplan: GraphQLSelectionSet {
                public struct Fragments {
                    public var gameplan: Backend.Gameplan {
                        get {
                            return Backend.Gameplan(unsafeResultMap: self.resultMap)
                        }
//snip

Actual outcome:

Backend.TheThingQuery.Data.Gameplan.Fragments type contains a var of type "Gameplan" which Swift interprets as a reference to Backend.TheThingQuery.Data.Gameplan.

Referencing the data in this fragment will result in compile-time errors because it contains the fields of the query's gameplan field, and not those of the fragment.

public extension Backend {
    final class TheThingQuery: GraphQLQuery {
        public struct Data: GraphQLSelectionSet {
            public struct Gameplan: GraphQLSelectionSet {
                public struct Fragments {
                    public var gameplan: Gameplan {
                        get {
                            return Gameplan(unsafeResultMap: self.resultMap)
                        }
//snip

How to reproduce the issue:

Use a fragment with the same name as a field that contains the field implementing the fragment.

Versions

0.40.3

RobinDaugherty avatar Jul 28 '21 16:07 RobinDaugherty

Nice work @RobinDaugherty 👏

On the project I'm currently working on, this issue is forcing us to rewrite valid query/fragments specifically for iOS to work around it. Is there any plan to get the linked pull request merged?

filipe-lemos avatar Oct 28 '21 13:10 filipe-lemos