graphql-js
graphql-js copied to clipboard
Feature Request: Allow interfaces to resolve to other interfaces
I originally raised this in Apollo Server and was told that it's actually implemented here.
Suppose I have the following schema:
interface Node {
id: ID!
}
interface Product implements Node {
id: ID!
price: Float!
}
type Food implements Product & Node {
id: ID!
price: Float!
expirationDate: String
}
I'd like to set up my resolvers for Node and Product like so:
const Node = {
__resolveType(node) {
if (node.price)
return 'Product';
return null;
}
}
const Product = {
__resolveType(product) {
if (product.expirationDate)
return 'Food'
return null;
}
}
In the current implementation of graphql-js, the Node resolver will result in an error because it resolves to Product, an interface type. This is despite the fact that Prodcut goes on to resolve to a concrete type. To make this work, the developer has to add logic for resolving Food to both the Product and Node resolver. This introduces code duplication, which becomes worse as more implementations of Product are added, and especially if other interfaces that implement Node and have own implementations are introduced.
I propose that it would be easier for the developer to maintain their resolvers if resolution of interface types could be chained. For the Node resolver in the example, that would mean when it resolves to Product, it goes on to use Product's __resolveType to resolve to the concrete type Food.
I think i have a similar issue so i add here my case :
Suppose I have the following schema:
enum MessageType {
message
action
}
interface Message {
type : MessageType!
}
type Action implements Message {
type : MessageType!
action : String
}
type Text implements Message {
type : MessageType!
text : String
}
type Document {
id: ID!
}
union TransactionData =
Message
| Document
enum TransactionType {
message
document
action
}
type Transaction {
id: ID!
type: TransactionType!
data: TransactionData!
}
I can't use interface in union even i have a __resolveType defined for Action and Text in MessageResolver.
I have to define union like that :
union TransactionData =
Action
| Text
| Document
and can't use Message resolver.
@gwenker => I think your comments are unrelated to a resolveType hiearchy, but is related to discussion at https://github.com/graphql/graphql-spec/issues/711