From 9f55acf9327114658a647cd2ac6edb9d0b96527e Mon Sep 17 00:00:00 2001 From: Jimmy ESCRICH Date: Thu, 14 Mar 2019 11:44:08 +0100 Subject: [PATCH] Improve documentation on dataloader using GraphQlBundle Signed-off-by: Jimmy ESCRICH --- README.md | 208 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 160 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 7ea865f..fa161ca 100644 --- a/README.md +++ b/README.md @@ -90,85 +90,197 @@ Here the list of existing promise adapters: This bundle can be use with [GraphQLBundle](https://github.com/overblog/GraphQLBundle). Here an example: -* Bundle config +* First create your service. We will use the Webonyx promise adapter ```yaml -#graphql +#config/services.yaml +services: + graphql_promise_adapter: + class: Overblog\DataLoader\Promise\Adapter\Webonyx\GraphQL\SyncPromiseAdapter + public: true + + + ### + # Force the overblog promise adapter to use the webonyx adapter + ### + Overblog\PromiseAdapter\PromiseAdapterInterface: + class: Overblog\PromiseAdapter\Adapter\WebonyxGraphQLSyncPromiseAdapter + arguments: + - "@graphql_promise_adapter" + + ### + # Add magic configuration to load all your dataLoader + ### + App\Loader\: + resource: "../src/Loader/*" +``` + +* Now configure the packages + +```yaml +#config/packages/graphql.yaml overblog_graphql: - definitions: - schema: - query: Query + #[...] services: - promise_adapter: "webonyx_graphql.sync_promise_adapter" + promise_adapter: "graphql_promise_adapter" -#dataloader +#config/packages/dataloader.yaml overblog_dataloader: defaults: - promise_adapter: "overblog_dataloader.webonyx_graphql_sync_promise_adapter" - loaders: - ships: - alias: "ships_loader" - batch_load_fn: "@app.graph.ships_loader:all" + promise_adapter: "graphql_promise_adapter" ``` -* Batch loader function +* Create an abstract class GenericDataLoader -```yaml -services: - app.graph.ship_repository: - class: AppBundle\Entity\Repository\ShipRepository - factory: ["@doctrine.orm.entity_manager", getRepository] - arguments: - - AppBundle\Entity\Ship +```php +createAll($this->find($ids)); + }, + $promiseAdapter + ); + } + + /** + * @param array $ids + * + * @return array + */ + abstract protected function find(array $ids): array; +} ``` +* Now create a DataLoader for all your entities. For example user + ```php promiseAdapter = $promiseAdapter; - $this->repository = $repository; + /** + * @var UserRepository + */ + private $userRepository; + + /** + * @param UserRepository $userRepository + * @param PromiseAdapterInterface $promiseAdapter + */ + public function __construct( + UserRepository $userRepository, + PromiseAdapterInterface $promiseAdapter + ) { + parent::__construct($promiseAdapter); + $this->userRepository = $userRepository; } - public function all(array $shipsIDs) + /** + * @inheritdoc + */ + protected function find(array $ids): array { - $qb = $this->repository->createQueryBuilder('s'); - $qb->add('where', $qb->expr()->in('s.id', ':ids')); - $qb->setParameter('ids', $shipsIDs); - $ships = $qb->getQuery()->getResult(); - - return $this->promiseAdapter->all($ships); + return $this->userRepository->findById($ids); } } -``` +``` * Usage in a resolver ```php - public function resolveShip($shipID) +userDataLoader = $userDataLoader; + $this->userRepository = $userRepository; + } + + /** + * @param int $id + * + * @return User + */ + public function resolveEntity(int $id) { - $promise = $this->container->get('ships_loader')->load($shipID); + return $this->userDataLoader->load($id); + } + + /** + * @param Argument $args + * + * @return object|\Overblog\GraphQLBundle\Relay\Connection\Output\Connection + * @throws \Exception + */ + public function resolveList(Argument $args) + { + $paginator = new Paginator(function ($offset, $limit) { + $ids = $this->userRepository->paginatedUsersIds($offset, $limit); + + return $this->userDataLoader->loadMany($ids); + }, Paginator::MODE_PROMISE); - return $promise; + return $paginator->auto($args, function() { + return $this->userRepository->count([]); + }); } + + /** + * {@inheritdoc} + */ + public static function getAliases(): array + { + return [ + 'resolveEntity' => 'User', + 'resolveList' => 'Users', + ]; + } +} ``` This is an example using the sync promise adapter of Webonyx.