-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability to inject the ResolveInfo in methods args #514
Comments
This is the way to go also for regular resolver, allowing the injection base on the type declaration or the args name. But this a long run so maybe we should start by accepting the graphql resolver base arguments ( value, info, context, rootValue). |
I'm not sure what you mean by regular resolver. When the arguments list is explicit, we can already use the For the auto-guessed arguments with annotations, I made it work by checking the class of the argument for the |
Hi Vincz sorry for the late reply I'm working on a service that will ease the injection of contextual resolver args. The new service will allow getting current resolver args (value, args, context, info) without having to inject each of them. Maybe this new feature could ease this implementation ? |
@mcg-web Could you provide an example of the config and how it would be used in a resolver? |
Yeah, I am also struggling with this. Auto guessing does not work and I don't know how exactly to explicitly specify the parameters, as it is not very well described in the docs. Tried with An example how to do it properly until auto guessing is implemented will be great. |
@Sh1d0w you should omit the |
@murtukov Sorry if I have misread the documentation. I was referring to the examples given here and here. However I am still struggling to inject ResolveInfo via explicit declarations in annotations, can you help me make this work:
The above throws an exception:
If I remove ResolveInfo argument and the resolve entry in annotations everything works. But I need to access the ResolveInfo data. |
@Sh1d0w It should work. It looks like a cache problem. Can you clear and warmup it? |
@Vincz @mcg-web Here is a yaml example: Mutation:
type: object
config:
fields:
createPost:
type: Post
resolve: App\GraphQL\Mutation\PostMutation::create
args:
# ... Basically we only point to a method. Now you might be asking yourself this questions:
All other arguments could be distinguished by the class/interface name ($args, $info, $context). It's also possible to autowire services directly into resolver by type hints. It can be done relatively easy. I don't know how it would be done with annotations. I need first to read all documentation about it and get familiar with its logic. |
@mcg-web since the |
I think whether the one way or the other way is better depends on the situation.
I thought of exact this. There are a few different way doing this, not only via name, but for example also 1. via ordering, 2. interfaces that provide hints of ordering and source (value, info, input). Each of them with advantages and disavantages. But the current solution has also disadvantages, its hard to find a perfect solution. We should rather ask
For non- |
Example solution for name collission: interface ResolverParameterMapInterface
{
const VALUE = 'value';
const INPUT = 'input';
const INFO = 'info';
public static function getResolverParameterMap(): array;
} Example solution for name collission: class MyResolver implements ResolverParameterMapInterface
{
public function fieldA($value, $info, $filters, $options)
{
}
public function fieldB($value, $filters)
{
}
public static function getResolverParameterMap(): array
{
return [
// this is only needed in edge-cases
// provides order and source, rest fetched via arg-name in resolver signature
// name collision only possible between VALUE|INFO & INPUT, but not between INPUT's
'fieldA' => [self::VALUE, self::INFO, self::INPUT, self::INPUT],
'fieldB' => [self::VALUE, self::INPUT],
];
}
} The solution for incompatibility in the byte-ranges valid for names in graphql vs. php could be the same as this, just as a name map |
Hi @akomm, I didn't read all new messages yet, but I want to say one thing immediately: No, webonyx doesn't provide any hooks, so right now the only place to get // ...
'resolve' => function ($value, $args, $context, ResolveInfo $info) use ($globalVariable) {
// here you can add any extra code, for example get a service:
$manager = $globalVariable->get('container')->get('App\Manager\User');
// ... or analyse the target resolver's type-hints with ReflectionFunction
return $globalVariable->get(/* resolver name */)->resolve([/* resolver arguments */]);
},
// ... I have already mentioned in this PR, that I use the method So if you are going to put some extra code, keep in mind that method. |
@akomm Btw I am currently working on the Hydrator. I will open an issue to share my views on its implementation (some points are changed since our last discussion) |
Also mentioned it before your PR in other issue here. For me its a sign, that its a common issue. Maybe worth a shot doing a PR on the lib so you can provide a callback to the executor/facade they provide, so bundles like this can then call such a callback to trigger an event. |
@akomm I am not familiar with the webonyx well enough, to open a PR for that lib. What about you? |
@murtukov this is what I am talking about. I just have to many construction zones. So I can not tell when I can do it. Before I got time to get my hands on the field(s) builder type emitting addition, it took very long just as an example. |
It happens to be I once had to figure this out when I wrote some PR for Zend\Config PHP allows almost any name, including null-bytes. In special semantic context, like you normally use in code its however limited to: I verified the validity of this statement. Also note it does not treat namespaces, but we do not care about namespaces here. GraphQL's spec for names is a subset of PHP's spec, so mapping from GraphQL to PHP should be safe. PHP adds some ranges outside ASCII on top of it, so the other way around is not safe. |
Here is my solution. This way you can add ResolveInfo as an argument to query function. <?php
declare(strict_types=1);
namespace App\Resolver;
use App\Application\UseCase\GoodByIdHandler;
use GraphQL\Type\Definition\ResolveInfo;
use Overblog\GraphQLBundle\Annotation as GQL;
use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
#[GQL\Provider]
final class GoodResolver implements QueryInterface
{
private GoodByIdHandler $handler;
public function __construct(GoodByIdHandler $handler)
{
$this->handler = $handler;
}
#[GQL\Query(name: "getGoodById", type: 'Good', resolve: "query('App\\\Resolver\\\GoodResolver::getGoodById', args[\"id\"], info)")]
#[GQL\Arg(name: 'id', type: 'Int!')]
#[GQL\Description('Получение информации для товара по Id')]
public function getGoodById(int $id, ResolveInfo $info)
{
$requestedFields = $info->getFieldSelection();
return $this->handler->handle($id, $requestedFields);
}
} |
It would be great to be able to get the ResolveInfo in methods with auto-guessed arguments.
For example:
Wondering also if we should allow services injection. But it would mean that the args could be either special (like ResolveInfo), a service or regular GraphQL argument. Maybe would it be too much?
The text was updated successfully, but these errors were encountered: