Thank you for the reply! I was reading over the union documentation and from what I understand you can union multiple types together so different types can be returned on the same field, but I'm not sure that would resolve the issue as we'd need a type with the certified field from SkiPatrol, and the privateLessons field from instructor on the same data item.
type Query {
allEmployees: Instructor | SkiPatrol
}
and you run the same query i mentioned above:
query {
allEmployees {
__typename
id
firstName
lastName
... on SkiPatrol {
certified
}
... on Instructor {
privateLessons
}
}
}
You'd still have the problem where the employee with id 0011 must be either a SkiPatrol (with the certified field) or instructor (with the privateLessons field) but I don't see how you'd be able to return someone with those fields from both types into an object that looks like this:
[
{
"roles": ["SkiPatrol","instructor"],
"id": "0011",
"firstName": "Jill",
"lastName": "Johnson",
"certified": "true", <--I want both of these fields on the same record
"privateLessons": "true" <--I want both of these fields on the same record
},
]
I think a better way to rephrase my question would be: Is there a way to have types that compose multiple other types? Similar to how in object oriented programming you can have a class that inherits multiple other classes to combine all methods and properties from both classes.
This is a really interesting question. I've been looking at the implementation and didn't find a viable solution so far. The problem seems to be related to the way the __resolveType method is implemented. It's designed to force you to return a type name as a String and just one. Clearly that's part of the GraphQL declarative nature
Thanks for the reply! This is actually exactly how I ended up implementing my schema! I have a file called CombinationTypes that defines all the different permutations of combined interfaces. When new combos are needed it's as simple as adding them to the schema since the interfaces already have the resolvers mapped to them. I have a "base" interface (like you have here with employee) that every combination type implements, and then I have a json object that maps possible values of fields on the base interface to all the various combo types. It's not in production yet, but it actually works very well.
Maybe I'm not getting it right, but it sounds to me as something you might achieve in a more GraphQL style by using Federation, Schema Composition and Apollo Gateway.
Here a link to the documentation and 2 excellent videos
Thank you for the reply! I was reading over the union documentation and from what I understand you can union multiple types together so different types can be returned on the same field, but I'm not sure that would resolve the issue as we'd need a type with the certified field from SkiPatrol, and the privateLessons field from instructor on the same data item.
so you might have in your schema:
enum Role{
SkiPatrol
Instructor
}
interface Employee {
id: ID!
firstName: String!
lastName: String!
role: [Role!]!
}
type Instructor implements Employee {
id: ID!
firstName: String!
lastName: String!
level: Int!
privateLessons: Boolean!
role: [Role!]!
}
type SkiPatrol implements Employee {
id: ID!
firstName: String!
lastName: String!
certified: Boolean!
aviLevel: Int!
role: [Role!]!
}
type Query {
allEmployees: Instructor | SkiPatrol
}
and you run the same query i mentioned above:
query {
allEmployees {
__typename
id
firstName
lastName
... on SkiPatrol {
certified
}
... on Instructor {
privateLessons
}
}
}
You'd still have the problem where the employee with id 0011 must be either a SkiPatrol (with the certified field) or instructor (with the privateLessons field) but I don't see how you'd be able to return someone with those fields from both types into an object that looks like this:
[
{
"roles": ["SkiPatrol","instructor"],
"id": "0011",
"firstName": "Jill",
"lastName": "Johnson",
"certified": "true", <--I want both of these fields on the same record
"privateLessons": "true" <--I want both of these fields on the same record
},
]
I think a better way to rephrase my question would be: Is there a way to have types that compose multiple other types? Similar to how in object oriented programming you can have a class that inherits multiple other classes to combine all methods and properties from both classes.
This is a really interesting question. I've been looking at the implementation and didn't find a viable solution so far. The problem seems to be related to the way the
__resolveType
method is implemented. It's designed to force you to return a type name as a String and just one. Clearly that's part of the GraphQL declarative natureAnd depending on the order of the early returns you'll end up having the first match.
A possible workaround might be to have multiple interfaces:
and resolve it like this
obviously this is just a hint and probably not the best practice for production quality code, but it might help you think something more elegant
Thanks for the reply! This is actually exactly how I ended up implementing my schema! I have a file called CombinationTypes that defines all the different permutations of combined interfaces. When new combos are needed it's as simple as adding them to the schema since the interfaces already have the resolvers mapped to them. I have a "base" interface (like you have here with employee) that every combination type implements, and then I have a json object that maps possible values of fields on the base interface to all the various combo types. It's not in production yet, but it actually works very well.
Maybe I'm not getting it right, but it sounds to me as something you might achieve in a more GraphQL style by using Federation, Schema Composition and Apollo Gateway.
Here a link to the documentation and 2 excellent videos
apollographql.com/docs/apollo-serv...
youtube.com/watch?v=v_1bn2sHdk4
youtube.com/watch?v=OFT9bSv3aYA
I hope you find this useful.