Search code examples
graphqlaws-amplifyaws-appsync

Graphql - How to include schema from other types


Let us say I have the following type:

type Foo {
  id: ID!
  field1: String
}

Now, I wish to define another type, which includes the earlier type. Something like this:

type Bar {
  ...Foo,
  field2: String
}

How do I achieve the above in graphql? I want to basically first create a type, and then include that type in the definition of other types so that I don't have to type all the attributes multiple times.

I am using Amplify / AWS Appsync so if there's any special directive that I could use that would also be helpful


Solution

  • GraphQL has the concept interfaces for this. Appsync, AWS's GraphQL implementation, supports interfaces.

    [Edit:] GraphQL does not support "...spread" syntax for interfaces. Fields are defined explicitly. Spread syntax does figure in GraphQL, but in the form of Fragments, resuable units of fields for reducing repetition in queries.

    interface Character {
      id: ID!
      name: String!
      friends: [Character]
      appearsIn: [Episode]!
    }
    
    type Human implements Character {
      id: ID!
      name: String!
      friends: [Character]
      appearsIn: [Episode]!
      starships: [Starship]
      totalCredits: Int
    }
    
    type Droid implements Character {
      id: ID!
      name: String!
      friends: [Character]
      appearsIn: [Episode]!
      primaryFunction: String
    }
    

    Amplify, which automagically creates AppSync schemas, resolvers and data sources, is apparently a more difficult story. The amplify-cli repo has an open feature request, Does the GraphQL Transformer support interfaces?. I am no Amplify expert, but a quick look at the loooong feature request comment thread suggests the answer for Amplify is "not out-of-the-box", but "maybe works in narrow circumstances or with advanced customization".