How to Inherit or Extend typeDefs in GraphQL

Viewed 21748

I have a type User. Users can also be a type TeamMember. The only difference between a User and TeamMember is an added field teamRole: String. So, I’d love to do something like the following to avoid having to redundantly define all the user's fields…

  type User {
    id: ID!,
    name: String,
    (many other field defs)
  }

  type TeamMember extends User  {
    teamRole: String,
  }

Anyone aware of a syntax for this? I thought extend would be the answer, but it seems more like javascript’s prototype

2 Answers

Using a schema transpiler like graphql-s2s to achieve inheritance is probably overkill, and graphql-s2s is outdated as of 2021.

Have a look at this Apollo Server directive: https://github.com/jeanbmar/graphql-inherits

const typeDefs = gql`
  directive @inherits(type: String!) on OBJECT

  type Car {
    manufacturer: String
    color: String
  }
  
  type Tesla @inherits(type: "Car") {
    manufacturer: String
    papa: String
    model: String
  }
`;

class InheritsDirective extends SchemaDirectiveVisitor {
    visitObject(type) {
        const fields = type.getFields();
        const baseType = this.schema.getTypeMap()[this.args.type];
        Object.entries(baseType.getFields()).forEach(([name, field]) => {
            if (fields[name] === undefined) {
                fields[name] = field;
            }
        });
    }
}
Related