-
Notifications
You must be signed in to change notification settings - Fork 225
I'm implementing a resolver that add a field to an existing type and I want to access the the value of this object type (to get its id and do some sql queries for example)
I might have missed it but I couldn't find how to do this easily. I first tried something like this:
#[GQL\Provider] final class UserExtension { #[GQL\Query(targetTypes: 'User')] public function something(User $user): int { return $this->computeSomething($user->id); } }
hoping that it would get auto-injected, but it's not (I was not really expecting to work, but it would be nice to be able to implement something like that, something à la Symfony ValueResolverInterface like discussed in #875 would be nice)
next step was to specify the $resolve argument of #[GQL\Query], and after a few tries I go it working with this:
#[AsAlias('gql.user.something', public: true)] #[GQL\Provider] final class UserExtension { #[GQL\Query( targetTypes: 'User', name: 'something', resolve: '@=call(service("gql.user.something").something, [value])', )] public function fake(): array { throw new \LogicException('TODO: figure out how we can get rid of this fake method'); } public function something(User $user): int { return $this->computeSomething($user->id); } }
but this means:
- I need to make the service (or an alias as in my example) public to be able to call it in the
resolve:expression - I can't have arguments on the method with the
#[GQL\Query]attribute as the bundle would try to expose them as GraphQL arguments
but at least it works :)
then I had a case where I want to have the value and a GraphQL argument, so I tried something like this:
#[AsAlias('gql.user.something', public: true)] #[GQL\Provider] final class UserExtension { #[GQL\Query( targetTypes: 'User', name: 'something', resolve: '@=call(service("gql.user.something").something, [value, ...args])', )] public function fake(int $foo): array { throw new \LogicException('TODO: figure out how we can get rid of this fake method'); } public function something(User $user, int $foo): int { return $this->computeSomething($user->id, $foo); } }
but this doesn't work because unpacking with ... isn't supported in expressions, so [value, ...args] doesn't work.
Is there a better way to do this? I would really like to this with attributes on DTO instead of doing too much stuff "manually" so that everything is less error-prone.
maybe something like this:
#[GQL\Provider] final class UserExtension { #[GQL\Query(targetTypes: 'User')] public function something( #[GQL\Expr('value') User $user, int $foo,, ): int { return $this->computeSomething($user->id, $foo); } }
wdyt? or again, maybe I've missed something?
thank you,
All reactions
Replies: 2 comments 2 replies
Hi @mathroc! You are right, the current implementation is far from ideal. We are required to make our providers public and we are fairly limited in term of parameters injection.
At the moment, the only way I see would be something like this (didn't tried it):
#[AsAlias('gql.user.something', public: true)] #[GQL\Provider] final class UserExtension { #[GQL\Query( targetTypes: 'User', name: 'something', resolve: '@=call(service("gql.user.something").something, [value, args["foo"]])', )] #[GQL\Arg(name='foo', type: 'Int')] public function something(User $user, int $foo): int { return $this->computeSomething($user->id, $foo); } }
All reactions
thx! didn't think about args["foo"] 🤦 that part works 👌
but I still need the intermediate function, without it, I have this error:
Argument n°1 "$user" on method "something" cannot be auto-guessed from the following type guessers: [Type Hint] No corresponding GraphQL scalar,enum,input found for class "User"
an easy fix would be to implement something like this:
public function something(#[GQL\Arg(skip: true)] User $user, int $foo): int
but it's a bit annoying to introduce this complexity for a workaround. but the more long-term solution would probably be quite more work
ps: btw, I know #[GQL\Arg] should be on the method, not the argument. would you be open to a merge request supporting them on arguments as-well?
All reactions
I think we could work from this PR: #728 if we wanted to improve the ArgumentsTransformer by allowing the users to define their owns transformer and to define a bunch automatically (like ResolveInfo, UserInterface, ValueInterface) specifically for the annotations/attributes.
@mcg-web was working on global improvements on the resolution but it was 3 years ago and I don't think he has a lot of time this day.
I don't have either, but I'll be willing to help you as much as I can if you want.
All reactions
Interesting :) will have a look