Reference to interface array not able to relate back array items

To facilitate better answering of questions, if you have a question, please fill in the following info. Otherwise, please delete the template.

What I want to do

In theory I should be able to reference an interface array which would be an array of the types that are implements and then have those related back to the implemented node. What I want is to be able to reference the one array which can be fed by multiple different types which are related back to that type.

What I did

I created an interface which is implemented by 2 types. These types I related to type Artist, referencing a relationship which references an array of the interface (Artist-artists_role).
I get this error:
resolving updateGQLSchema failed because input: Type Artist_project; Field artist: @hasInverse is required to link the fields of same type, but the field artists_role is of the type [Artist_role!] instead of Artist_project. To link these make sure the fields are of the same type.

Dgraph metadata

interface Artist_role {
id:ID!
active: Boolean! # if currently active in project
}

type Artist_project implements Artist_role {
id: ID!
artist: [Artist]! @hasInverse(field: artists_role)
project: [Project]! @hasInverse(field: artists_project)
active: Boolean! # if currently active in project

}

type Artist_collection implements Artist_role {
id: ID!
artist: [Artist]! @hasInverse(field: artists_role)
active: Boolean! # if currently active in project
}

type Artist {
id: ID!
user: [User] @hasInverse(field: artists)
artists_role: [Artist_role!]

It doesn’t seem like this is possible, is there a different way to accomplish the same thing?

Just move the artist: [Artist]! @hasInverse(field: "artists_role") to the interface instead of the implementing types and it will work.


interface Artist_role {
  id:ID!
  active: Boolean! # if currently active in project
  artist: [Artist]! @hasInverse(field: "artists_role")
}

type Artist_project implements Artist_role {
  id: ID!
  project: [Project]! @hasInverse(field: "artists_project")
  # NOTE: not needed to redefine here
  # active: Boolean! # if currently active in project
}

type Artist_collection implements Artist_role {
  id: ID!
  # NOTE: not needed to redefine here
  # active: Boolean! # if currently active in project
}

type Artist {
  id: ID!
  user: [User] @hasInverse(field: "artists")
  artists_role: [Artist_role!]
}

# Assumed the following type/interface to test schema deployment
interface User {
  id:ID!
  username: String! @id
  artists: [Artist] @hasInverse(field: "user")
}

# Assumed the following type/interface to test schema deployment
interface Project {
  id: ID!
  artists_project: [Artist_project] @hasInverse(field: "project")
}

Some points to possibly help in the future:

  • In Dgraph, when deploying a schema, you do not need to inherently redefine all fields in implementing types. This is only a specific thing within Dgraph, as GraphQL spec, says you have to redefine all interfaces field. Dgraph takes your basic types and does these steps without causing you to define them manually.
  • Array in Dgraph, are not actually arrays, like JSON, and most other programming languages, consider arrays. Instead, they behave more like sets in that no duplicates are stored, and neither is the order of items preserved.
  • You don’t have to precisely define the @hasInverse directive on both sides of the relationship. This is just a preference and one that I do as well to help with readability to show what is linked somewhere from either side and what is not linked.

Thanks! For some reason I thought relationships could not be included in the interface. Just curious, what happens if you do include fields in the implements that are in the interface can this “break” the DB?

It should work and only throw an error if you have different types or different search directives.

1 Like