Apollo-tooling: No code generated for interface inline fragments

Created on 28 Jan 2017  路  10Comments  路  Source: apollographql/apollo-tooling

I can use objects as inline fragments, but for interface fragments no code is generated. Shouldn't this be possible?

{
... on ClosedEvent {
        # object, works
    }  
... on IssueEvent {
        # interface, no code is generated
    }
}

(Using Swift, but saw similar results with the other targets.)

馃悶 bug

Most helpful comment

I have an example for this:

Schema:
zoo.graphql

interface Feedable {
    _id: ID!,
    kind: String!
    feedWith: String!
}


interface Reptile {
    scaleSkin: String!
}

type Crocodile implements Feedable, Reptile {
    _id: ID!,
    kind: String!
    feedWith: String!
    scaleSkin: String!

    victims: Int!
}

type Iguana implements Feedable, Reptile {
    _id: ID!,
    kind: String!
    feedWith: String!
    scaleSkin: String!

    age: Int!
}

root.graphql

type Query {
    getZoo: [Feedable!]!
}

schema {
    query: Query
}

And now I setup a very simple query with some fragments:
zooQuery.graphql

query getZoo {
    getZoo {
        ...FeedableFragment
    }
}

FeedableFragment.graphql

fragment ReptileFragment on Reptile {
    scaleSkin
}

fragment CrocodileFragment on Crocodile {
    victims
}

fragment IguanaFragment on Iguana {
    age
}

fragment FeedableFragment on Feedable {
    _id
    kind,
    feedWith

    ... on Reptile {
        ... ReptileFragment
    }

    ... on Crocodile {
        ... CrocodileFragment
    }

    ... on Iguana {
        ... IguanaFragment
    }
}

And now I check the generated interfaces and I have this:

export interface FeedableFragment {
  _id: string;
  kind: string;
  feedWith: string;
  _id: string;
  kind: string;
  feedWith: string;
  _id: string;
  kind: string;
  feedWith: string;
}

Notice the property duplication and the fact that all inline fragment information is missing.

All 10 comments

Hey @Anviking thanks for the report, this seems to be an issue with the common code between the targets, we definitely need to handle interfaces better... We'll take a look but we also invite you to try to tackle the problem yourself in the meantime, we'll be happy to help and give you pointers for you to do your first contributions on this project. However, don't worry if you can't, that's something we'll take a look at anyway.

@Anviking @rricard: I'm not sure I would classify this as a bug (and certainly not an easy one 馃槉), but I can see how the behavior can be confusing. And maybe we should reconsider it.

Looking at the Swift target for now, we only generate as<Type> methods for object types. These do contain fields selected on interfaces however.

So using your example (and assuming it is from the GitHub schema), given that ClosedEvent implements IssueEvent, any fields selected on IssueEvent will be added to the generated fragment for ClosedEvent (and to any other fragments for object types implementing the same interface).

@martijnwalraven Maybe I classified it too fast but there is definitely an issue. The example given, even if we could avoid it should still work: that is a correct graphql document. I thought it could be easy but indeed, before we refactor, and after evaluating again the code, I also think it'll be hard to fix...

@rricard: Hmmm, maybe I don't understand the issue. But I definitely wasn't suggesting we don't support inline fragments on interfaces. The query above should work, but the fields selected on IssueEvent will be added to the fragment generated for ClosedEvent. So to be absolutely clear, when you write the query as above, you will get an asClosedEvent property returning a fragment that also includes all fields selected on IssueEvent (in the ... on IssueEvent part of the query).

I verified this works for Swift with the StarWars schema for what seems to be a similar situation. But if there is indeed a problem, it would really help to have a complete failing example I could use to reproduce it.

I can confirm that using the TypeScript code generation, the fields coming from inline fragments with type conditions are missing from the interface that is supposed to describe the results of the query.

I have an example for this:

Schema:
zoo.graphql

interface Feedable {
    _id: ID!,
    kind: String!
    feedWith: String!
}


interface Reptile {
    scaleSkin: String!
}

type Crocodile implements Feedable, Reptile {
    _id: ID!,
    kind: String!
    feedWith: String!
    scaleSkin: String!

    victims: Int!
}

type Iguana implements Feedable, Reptile {
    _id: ID!,
    kind: String!
    feedWith: String!
    scaleSkin: String!

    age: Int!
}

root.graphql

type Query {
    getZoo: [Feedable!]!
}

schema {
    query: Query
}

And now I setup a very simple query with some fragments:
zooQuery.graphql

query getZoo {
    getZoo {
        ...FeedableFragment
    }
}

FeedableFragment.graphql

fragment ReptileFragment on Reptile {
    scaleSkin
}

fragment CrocodileFragment on Crocodile {
    victims
}

fragment IguanaFragment on Iguana {
    age
}

fragment FeedableFragment on Feedable {
    _id
    kind,
    feedWith

    ... on Reptile {
        ... ReptileFragment
    }

    ... on Crocodile {
        ... CrocodileFragment
    }

    ... on Iguana {
        ... IguanaFragment
    }
}

And now I check the generated interfaces and I have this:

export interface FeedableFragment {
  _id: string;
  kind: string;
  feedWith: string;
  _id: string;
  kind: string;
  feedWith: string;
  _id: string;
  kind: string;
  feedWith: string;
}

Notice the property duplication and the fact that all inline fragment information is missing.

I'm having this issue as well. This should probably create a discriminated union type using the __typename as the discriminator.

Hello @martijnwalraven, is there a plan to address this issue?

@IgorLipovac: Is this still an issue with the latest version? There have been some changes in this area for the Flow/TypeScript targets recently.

Looks like this is fixed. I just tried it with the zoo example above. If anyone has another case that showcases a bug, please re-open or file another issue :), thanks!

Was this page helpful?
0 / 5 - 0 ratings