Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to implement multiple interfaces in GraphQL?

Tags:

graphql

Is it possible to specify a type that implements multiple interfaces within a GraphQL schema? If so, how would this be accomplished?

like image 592
puradox Avatar asked Jul 21 '17 00:07

puradox


People also ask

Can an interface implement another interface GraphQL?

An interface cannot implement another interface.

Can there be multiple interfaces?

Yes, it is possible. This is the catch: java does not support multiple inheritance, i.e. class cannot extend more than one class. However class can implement multiple interfaces.

What are GraphQL interfaces?

Like many type systems, GraphQL supports interfaces. An Interface is an abstract type that includes a certain set of fields that a type must include to implement the interface. For example, you could have an interface Character that represents any character in the Star Wars trilogy: interface Character { id: ID!

When would you use a GraphQL interface?

GraphQL interfaces are useful to solve problems like above where we want to have the returned type possibly from different types. For this to work, we can define a Union type that can resolve to either one of Book , Movie or Album and then each type can have its own set of fields.


3 Answers

Yes. As outlined in the spec:

An object type may declare that it implements one or more unique interfaces.

Keep in mind that the resulting object must be a "super-set of all interfaces it implements" -- it must implement all the fields each interface has and these fields cannot conflict. For example, if Interface A and Interface B both have a field called something, the type of that field must be the same for both interfaces in order for an Object Type to implement both interfaces.

Here's a simple example that you can open in CodeSandbox and play around with.

Note: As others have pointed out, using a comma to separate the interfaces is no longer supported -- please use an & (ampersand) instead.

const { ApolloServer, gql } = require("apollo-server");

const typeDefs = gql`
  type Query {
    someAnimal: Animal!
    someBird: Bird!
  }

  interface Bird {
    wingspan: Int!
  }

  interface Animal {
    speed: Int!
  }

  type Swallow implements Animal & Bird {
    wingspan: Int!
    speed: Int!
  }
`;

const resolvers = {
  Query: {
    someAnimal: (root, args, context) => {
      return { wingspan: 7, speed: 24 };
    },
    someBird: (root, args, context) => {
      return { wingspan: 6, speed: 25 };
    }
  },
  Bird: {
    __resolveType: () => "Swallow"
  },
  Animal: {
    __resolveType: () => "Swallow"
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

Please note that the spec now also allows interfaces to implement other interfaces.

When defining an interface that implements another interface, the implementing interface must define each field that is specified by the implemented interface... Transitively implemented interfaces (interfaces implemented by the interface that is being implemented) must also be defined on an implementing type or interface.

In GraphQL.js, this is supported as of version 15.0.0.

like image 96
Daniel Rearden Avatar answered Oct 25 '22 23:10

Daniel Rearden


It seems comma separating the interfaces doesn't work anymore. I had to use "&" instead to make it work (Apollo), see this answer https://stackoverflow.com/a/49521662/1959584

type Something implements First & Second
like image 14
Mikael Lirbank Avatar answered Oct 25 '22 23:10

Mikael Lirbank


I think yes, it should be possible as the specification describes on http://facebook.github.io/graphql/June2018/#sec-Interfaces.

Here is the example.

interface NamedEntity {
  name: String
}

interface ValuedEntity {
  value: Int
}

type Person implements NamedEntity {
  name: String
  age: Int
}

type Business implements NamedEntity & ValuedEntity {
  name: String
  value: Int
  employeeCount: Int
}
like image 6
diveintohacking Avatar answered Oct 25 '22 23:10

diveintohacking