GraphQL package for BNNVARA
##Installation
Using Composer:
composer require bnnvara/graphql-bundle
Enable the bundle in bundles.php
.
return [
...
BNNVARA\GraphQLBundle\BNNVARAGraphQLBundle::class => ['all' => true],
...
];
This document does not explain the inner workings of graphql. There are great resources available online to get familiair with graphql.
In this example we use the following Query:
public function __construct()
{
$config = [
'name' => 'Query',
'fields' => [
'user' => [
'type' => Types::user(),
'description' => 'Returns user by id (in range of 1-5)',
'args' => [
'id' => Types::nonNull(Types::id())
]
],
'viewer' => [
'type' => Types::user(),
'description' => 'Represents currently logged-in user (for the sake of example - simply returns user with id == 1)'
]
],
'resolveField' => function($val, $args, $context, ResolveInfo $info) {
return $this->{$info->fieldName}($val, $args, $context, $info);
}
];
parent::__construct($config);
}
public function user($rootValue, $args)
{
return DataSource::findUser($args['id']);
}
public function viewer($rootValue, $args, AppContext $context)
{
return $context->viewer;
}
To create a Query like this using the BNNVARA\GraphQLBundle you need to create to classes. Each implementing an interface:
The implementation of the QueryInterface looks as follows:
namespace Example\NameSpace;
class UserQuery implements QueryInterface
{
public function __construct(ResolverInterface $resolver)
{
$this->resolver = $resolver;
}
public function getName(): string
{
return 'user';
}
public function getQuery(): array
{
return [
'type' => Types::user(),
'description' => 'Returns user by id (in range of 1-5)',
'args' => [
'id' => Types::nonNull(Types::id())
]
];
}
public function getResolver(): ResolverInterface
{
return $this->resolver;
}
}
The implementation of the ResolverInterface looks as folows:
namespace Example\NameSpace;
class UserResolver implements ResolverInterface
{
public function resolve($val, $args, $context, ResolveInfo $info)
{
return DataSource::findUser($args['id']);
}
public function isSupported($val, $args, $context, ResolveInfo $info): bool
{
return $info->fieldName === 'user';
}
}
The last step to make a Query work is tagging the UserQuery service:
Example\NameSpace\UserQuery:
tags: ['bnnvara.graph_ql.query']
The bundle takes care of the rest
In progress
##Logger
The BNNVARA/GraphQLBundle implements the PSR\LoggerInterface. So it is possible to configure your own prefered logger.
By default the NullLogger included in de PSR\Log package is used. You can change the logger to, for example, the monolog
logger by creating config/packages/bnnvara_graphql.yaml
and add the following lines, where monolog.logger is the
name of the service you want to use:
bnnvara_graphql:
logger_service: monolog.logger
##Cache
IMPORTANT Only use caching for anonymous queries. All executed queries are cached, so if one of the query is not anonymous don't use this feature
Caching is disabled by default, but can be enabled easily. Doctrine/Cache is used as caching provider but not installed because caching is disabled by default. Doctrine cache can be installed with the following command:
composer require doctrine/doctrine-cache-bundle
The cache bundle is used to ease setting up the cache driver. To define a redis driver just create
app/config/packages/doctrine_cache.yaml
and add the following lines (don't forget to define the used variables):
doctrine_cache:
providers:
response_cache:
type: redis
redis:
host: "%env(REDIS_HOST)%"
port: "%env(REDIS_PORT)%"
Now the container contains a service with the name doctrine_cache.providers.response_cache
. Next step is to add
configuration for the cache:
bnnvara_graphql:
cache:
caching_driver: "%env(GRAPHQL_CACHING_DRIVER)%"
lifetime: "%env(GRAPHQL_CACHE_LIFETIME)%"
Now all succesful request will be cached. Enjoy!