2

Below is a query which is conceptually what I'm looking for. But, I cannot figure out how to implement... or even if it's possible.

query getMedia($id: ID!) {
  media(id: $id) {
    __typename
    title

    ... on Movie {
      fps
    }

    ... on Music {
      duration

      ... on Song {
        lyrics
      }

      ... on Composition {
        movements
      }
    }

  }

Basically, I have types of Media, if it's Music, there are different types of music. If the record is a "Song", I would expect this as a response:

{
  "media": {
    "__typename": "Song",
    "duration": 5.67,
    "title": "Some Song",
    "lyrics": "La de da de da de da de day oh",
  }
}

Is this possible?

Marco Daniel
  • 5,467
  • 5
  • 28
  • 36
Jesse Lee
  • 1,291
  • 1
  • 8
  • 20

1 Answers1

1

To be clear, your media field as it appears in your question would have to be an Interface, not a Union, since it includes at least one field that's common to all implementing types (title). Regardless, whether we're talking about Interfaces or Unions, the kind of syntax you're suggesting is not supported. Only object types can implement Interfaces. Similarly:

The member types of a Union type must all be Object base types; Scalar, Interface and Union types must not be member types of a Union. Similarly, wrapping types must not be member types of a Union.

Movie, Song and Composition will all need to extend the Media interface, and then they can be queries like so:

query getMedia($id: ID!) {
  media(id: $id) {
    __typename
    title

    ... on Movie {
      fps
    }

    ... on Song {
      duration
      lyrics
    }

    ... on Composition {
      duration
      movements
    }
  }
}

Unfortunately, that does mean some duplication in your inline fragments. The good news is, an object type can implement multiple interfaces, and implementing an interface does not preclude it from being included in one or more unions. So, if you need it, you can still create a Music interface or union and use that as a return type for a different field.

Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183