[x] Feature request
I would like to create a resolver for an interface type which has a property resolver
I should be able to define a resolver for an interface type and add property resolvers for virtual fields on that resolver. It should have access to services via constructor injection, etc.
@InterfaceType()
export class IExample {
}
@Resolver(of => IExample)
export class ExampleResolver {
constructor(
private readonly example: ExampleService
) { }
@ResolveProperty(type => Boolean)
public async foo(@Root() item: IExample) {
// this.example is available for this function
return false
}
}
If you have an interface type with multiple concrete types you want to be able to access it in gql like:
examples {
foo
}
Not
examples {
... on ConcreteType {
foo
}
}
Which it seems like right now the only way to do it is to promote the field to resolvers for each concrete type.
Nest version: ^6.7.2
For Tooling issues:
v12.8.0linuxBy the way the error I get when I try to do this is:
{
"code": "GRAPHQL_VALIDATION_FAILED",
"exception": {
"stacktrace": [
"GraphQLError: Cannot query field \"foo\" on type \"IExample\". Did you mean to use an inline fragment on \"ConcreteType\"?",
"..."
]
}
}
You can't query interfaces, you can only implement them.
EDIT:
It seems like I've misunderstood your question.
This is out of the scope (as it's not supported in the GraphQL spec)
It's not related to NestJS, but rather the GraphQL itself
I think you can, it clearly works for fields right on the object. I think that my problem may simply be that I didn't put the field on the interface though! I'll double check and follow up here.
Thanks.
@justinmchase nope you can't.
An interface in GraphQL is just like an interface in TS.
You need to implement a type with it before you can query it.
https://graphql.org/learn/schema/#interfaces
Well they're doing it even in that example you linked...
The character interface has a name field which you can then query without the concrete type. Of course the object you're returning has to match a concrete type in the union but you should be able to query fields on the interface type without having to use a concrete fragment.
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name # <-- this is a field on the interface
... on Droid {
primaryFunction
}
}
}
Imagine you want the name field to be a resolver which is the same for all implementers of Character. I'll play with it a little later, I think I forgot to put the field on my interface and that's whats really blocking me.
Looking at this more, adding the field to the interface doesn't help. I am getting a crash in type-graphql which I'm filing a bug over there for but I do think that this is a legitimate issue in this library and think this ticket should be re-opened.
I think its legitimate because I am able to do this with graphql without using this library and it is documented in their documentation and it is a limitation of this library that this isn't supported.
I think the example from the gql documentation for characters that @marcus-sa linked to is a good one, so this feature request / bug becomes how can I implement Character.name as a property resolver?
@InterfaceType()
export class Character {
@Field()
public name: string
}
@Resolver(of => Character ) // <-- this crashes my app
export class CharacterResolver {
constructor(
private readonly characters: CharacterService
) { }
@ResolveProperty(type => String)
public async name(@Root() character: Character) {
return this.charcters.resolveName(character)
}
}
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.