At present, to go on with your schema, you could do something like this:
type Account {
id: ID!
name: String! @search(by: [term])
projects: [Project] @hasInverse(field: account)
}
interface Project {
account: Account!
}
interface Production {
id: ID!
scenes: [Scene] @hasInverse(field: production)
}
type Series implements Project {
id: ID!
episodes: [Episode] @hasInverse(field: series)
}
type Film implements Project & Production
type Episode implements Production {
title: String
episodeNumber: String
series: Series
}
type Scene {
id: ID!
sceneNumber: Int!
production: Production!
}
Notice that I have removed the ID
field from Project
and added it to Production
, also, added ID
field to the types implementing Project
but not Production
.
This feels like avoiding the obstacles as long as you can, to make things work. But, doesn’t seem like a good approach in the long run as you may have a lot of types implementing Project
and then you may really want to have an ID
field in Project
.
The problem starts with Film
implementing both Project
and Production
, and let’s say if we had an ID
field in both Project
and Production
, then currently it would give an error because type Film
can’t have two ID
fields. So, what I thought of as a solution to this problem is a directive like @inheritID
, as shown in the below example. So, consider these two interfaces:
interface Project {
projectID: ID!
...
}
interface Production {
productionID: ID!
...
}
Now, you could either inherit the ID field from one of the implementing types, like this:
type Film implements Project & Production @inheritID(inherit: true, from: "Production")
OR, you could choose to define your own ID field in Film
, like this:
type Film implements Project & Production @inheritID(inherit: false) {
id: ID!
}
But, this directive itself may cause some problems with hasInverse
usage. I haven’t given a thought to that yet. I guess we need to think about this case a bit more to find a nice solution.