To ease development we created 2 types of resolver:
Query that should be used for resolving readonly actionsMutation that should be used for resolving writing actionsThis is just a recommendation.
Resolvers can be defined in 2 different ways:
You can declare a resolver (any class that implements Overblog\GraphQLBundle\Definition\Resolver\QueryInterface or Overblog\GraphQLBundle\Definition\Resolver\MutationInterface) in src/*Bundle/GraphQL or app/GraphQL and they will be auto discovered.
Auto map classes method are accessible by:
AppBundle\GraphQL\CustomResolver::myMethod)AppBundle\GraphQL\InvokeResolver for a resolver implementing the __invoke method) you can also alias a type by implementing Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface which returns a map of method/alias. The service created will autowire the __construct and Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer methods.Note:
'@=query("App\\GraphQL\\Resolver\\Greetings", args["name"])'.Example using an alias:
resolve: '@=query("say_hello", args["name"])'
<?php
# src/GraphQL/Resolver/Greetings.php
namespace App\GraphQL\Resolver;
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
class Greetings implements QueryInterface, AliasedInterface
{
public function sayHello($name)
{
return sprintf('hello %s!!!', $name);
}
/**
* {[@inheritdoc](https://github.com/inheritdoc)}
*/
public static function getAliases(): array
{
return ['sayHello' => 'say_hello'];
}
}
Example using a fully qualified method name:
resolve: '@=query("App\\GraphQL\\Resolver\\Greetings::sayHello", args["name"])'
Note: backslashes must be correctly escaped and respect the use of single and double quotes.
<?php
# src/GraphQL/Resolver/Greetings.php
namespace App\GraphQL\Resolver;
use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
class Greetings implements QueryInterface
{
public function sayHello($name)
{
return sprintf('hello %s!!!', $name);
}
}
Example using the class invoker:
resolve: '@=query("App\\GraphQL\\Resolver\\Greetings", args["name"])'
<?php
# src/GraphQL/Resolver/Greetings.php
namespace App\GraphQL\Resolver;
use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
class Greetings implements QueryInterface
{
public function __invoke($name)
{
return sprintf('hello %s!!!', $name);
}
}
This way SayHello resolver can be accessed with App\GraphQL\Resolver\Greetings.
You may also use the invoker to define a type-wide resolver with the resolveField option:
# config/graphql/types/MyType.types.yaml
MyType:
type: object
config:
resolveField: '@=query("App\\GraphQL\\Resolver\\Greetings", info, args.name)'
fields:
hello:
type: String
goodbye:
type: String
<?php
# src/GraphQL/Resolver/Greetings.php
namespace App\GraphQL\Resolver;
use GraphQL\Type\Definition\ResolveInfo;
use Overblog\GraphQLBundle\Definition\Resolver\QueryInterface;
class Greetings implements QueryInterface
{
public function __invoke(ResolveInfo $info, $name)
{
if($info->fieldName === 'hello'){
return sprintf('hello %s!!!', $name);
}
else if($info->fieldName === 'goodbye'){
return sprintf('goodbye %s!!!', $name);
}
else{
throw new \DomainException('Unknown greetings');
}
}
}
<?php
# src/GraphQL/Mutation/CalcMutation.php
namespace App\GraphQL\Mutation;
use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
use Overblog\GraphQLBundle\Definition\Resolver\MutationInterface;
class CalcMutation implements MutationInterface, AliasedInterface
{
private $value;
public function addition($number)
{
$this->value += $number;
}
/**
* {[@inheritdoc](https://github.com/inheritdoc)}
*/
public static function getAliases(): array
{
return ['addition' => 'add'];
}
}
addition mutation can be access by using App\GraphQL\Mutation\CalcMutation::addition or
add alias.
Here an example of how this can be done with DI autoconfigure:
services:
_defaults:
autoconfigure: true
Overblog\GraphQLBundle\GraphQL\Relay\:
resource: ../../GraphQL/Relay/{Mutation,Node}
Creating a service tagged overblog_graphql.query for queries
or overblog_graphql.mutation for mutations.
Using the php way examples:
services:
App\GraphQL\Resolver\Greetings:
# only for sf < 3.3
#class: App\GraphQL\Resolver\Greetings
tags:
- { name: overblog_graphql.query, method: sayHello, alias: say_hello } # add alias say_hello
- { name: overblog_graphql.query, method: sayHello } # add service id "App\GraphQL\Resolver\Greetings"
SayHello resolver can be access by using App\GraphQL\Resolver\Greetings::sayHello or
say_hello alias.
for invokable classes no need to use alias and method attributes:
services:
App\GraphQL\Resolver\Greetings:
# only for sf < 3.3
#class: App\GraphQL\Resolver\Greetings
tags:
- { name: overblog_graphql.query }
This way resolver can be accessed with service id App\GraphQL\Resolver\Greetings.
for mutation:
services:
App\GraphQL\Mutation\CalcMutation:
# only for sf < 3.3
#class: App\GraphQL\Mutation\CalcMutation
tags:
- { name: overblog_graphql.mutation, method: addition, alias: add }
addition mutation can be access by using App\GraphQL\Mutation\CalcMutation::addition or
add alias.
The default field resolver can be define using config:
overblog_graphql:
definitions:
default_field_resolver: 'my_default_field_resolver_service'
Default field resolver should be a callable service (implementing __invoke method)
Next step solving N+1 problem
How can I help you explore Laravel packages today?