Interfaces in GraphQL represented by DQL with multiple dgraph.type

This is a knowledge post to help others.

GraphQL Schema:

enum Diet {
  CARNIVORE
  HERBIVORE
}
interface Animal {
  id: ID!
  name: String! @search(by:[hash])
  diet: Diet
  predators: [Predatore]
}
type Predatore implements Animal {
  domesticated: Boolean
  prey: [Animal] @hasInverse(field: "predatores")
}

This would be represented in DQL schema

type Animal {
  Animal.name
  Animal.diet
  Animal.predators
}
type Predatore {
  Animal.name
  Animal.diet
  Animal.predators
  Predatore.domesticated
  Predatore.prey
}
Animal.name: string @index(hash) .
Animal.diet: string .
Animal.predators: [uid] .
Animal.domesticated: boolean .
Animal.prey: [uid] .

You will notice these things:

  • The GraphQL interface is modeled in DQL as a type since there is no “interface” understanding in DQL.
  • The fields (known as predicates in DQL) have the interface or type dotted notation.
  • The DQL type that implements the GraphQL interface inherits the same interface dotted predicate names.
  • The DQL edges don’t have the reverse directive and are actually two distinct predicates, one for either direction of the edge.
  • (Bonus) The enum field is represented in DQL as simply a string field. There is no control in DQL as to what string values this predicate can hold.

This information and schema mapping will need to be known and understood if you plan on importing data with bulk loader or live loader or if you need advanced DQL queries/mutations/upserts along with using GraphQL.

If you were to add a single node into this schema with RDF it would look like:

{
  _:predator1 <dgraph.type> "Animal" .
  _:predaror1 <dgraph.type> "Predator" .
  _:predator1 <Animal.name> "Lion" .
  _:predator1 <Animal.diet> "CARNIVORE" .
  _:predator1 <Predator.domesticated> "false" .
}

Hope this helps. If you have questions or suggestions to make this easier to understand comment below.

3 Likes

This is True if you are a Arab Sheikh in Dubai :stuck_out_tongue: LOL

2 Likes