Is it possible to have resolver written once for the interface so all the implemented types could use it?
In below example, I have the IStat implemented by other types. It has resolver which comes as an instance of a class (or could be anything) and need to be converted to a string.
interface IStat {
resource: String!
name: String!
}
type FileStat implements IStat {
resource: String!
name: String!
mtime: String!
}
type Content implements IStat {
resource: String!
name: String!
value: String!
}
type StreamContent implements IStat {
resource: String!
name: String!
value: String!
encoding: String!
}
instead of (which is working)
export const resolver = {
FileStat: {
resource(root, args, ctx) {
return convertToString(root.resource);
},
},
Content: {
resource(root, args, ctx) {
return convertToString(root.resource);
},
},
StreamContent: {
resource(root, args, ctx) {
return convertToString(root.resource);
},
},
}
````
to be following so we are writing `IStat` once and expected all the `types` implemented by it uses it.
export const resolver = {
IStat: {
resource(root, args, ctx) {
return convertToString(root.resource);
},
},
}
````
It's possible to inherit resolvers from an interface, but the more advanced use currently necessitates the use of makeExecutableSchema, which is also exported from apollo-server (and its variants). The key is to use inheritResolversFromInterfaces: true on makeExecutableSchema's options and pass the resulting schema to Apollo Server in place of typeDefs and resolvers.
I've mocked this up quickly in this Glitch, but here's the code, request and result:
import { ApolloServer, gql, makeExecutableSchema } from 'apollo-server';
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
interface IStat {
resource: String!
name: String!
}
type Content implements IStat {
resource: String!
name: String!
value: String!
}
type StreamContent implements IStat {
resource: String!
name: String!
value: String!
encoding: String!
}
type Query {
content: Content
stream: StreamContent
}
`;
// Provide resolver functions for your schema fields
const resolvers = {
IStat: {
resource(parent, args, context, { parentType }) {
return parentType.name; // (e.g. "Content", "StreamContent", etc.)
}
},
Query: {
content(parent, args, context, { returnType }) {
return {
name: "Some content",
value: "6",
};
},
stream() {
return {
name: "Stream name",
value: "8",
}
}
}
};
const schema = makeExecutableSchema({
typeDefs,
resolvers,
inheritResolversFromInterfaces: true
});
const server = new ApolloServer({ schema });
server.listen().then(({ url }) => {
console.log(`馃殌 Server ready at ${url}`)
});
{
content {
resource
name
}
stream{
resource
name
}
}
{
"data": {
"content": {
"resource": "Content",
"name": "Some content"
},
"stream": {
"resource": "StreamContent",
"name": "Stream name"
}
}
}
Does this look like it'd cover your use case? If so, I think some documentation here could go a long way. Particularly on our documentation for Unions and Interfaces.
I'll close this as there hasn't been any additional follow-up in quite some time. Hopefully the information I've previously provided above would be sufficient for anyone else who arrives at this issue in the future.
If anyone is still having problems with this, feel free to ask in the Apollo community on Spectrum.chat, where questions are better suited, in general.
Thanks!
The inheritResolversFromInterfaces: true works well and we should improve the documentation to add something about.
But ... I think the feature request is still relevant, because it could allow this feature without having to use makeExecutableSchema, which add some complexity
Most helpful comment
It's possible to inherit resolvers from an interface, but the more advanced use currently necessitates the use of
makeExecutableSchema, which is also exported fromapollo-server(and its variants). The key is to useinheritResolversFromInterfaces: trueonmakeExecutableSchema's options and pass the resultingschemato Apollo Server in place oftypeDefsandresolvers.I've mocked this up quickly in this Glitch, but here's the code, request and result:
Query
Response
Does this look like it'd cover your use case? If so, I think some documentation here could go a long way. Particularly on our documentation for Unions and Interfaces.