Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions core/data-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,78 @@ final class BlogPostItemDataProvider implements ItemDataProviderInterface, Seria
}
}
```

## Injecting Extensions (Pagination, Filter, EagerLoading etc.)

ApiPlatform provides a few extensions that you can reuse in your custom DataProvider.
Note that there are a few kind of extensions which are detailed in [their own chapter of the documentation](extensions.md).
Because extensions are tagged services, you can use the [injection of tagged services](https://symfony.com/blog/new-in-symfony-3-4-simpler-injection-of-tagged-services):

```yaml
services:
'App\DataProvider\BlogPostItemDataProvider':
arguments:
$itemExtensions: !tagged api_platform.doctrine.orm.query_extension.item
```

Or in XML:

```xml
<services>
<service id="App\DataProvider\BlogPostItemDataProvider">
<argument key="$itemExtensions" type="tagged" tag="api_platform.doctrine.orm.query_extension.item" />
</service>
</services>
```

Your data provider will now have access to the core extensions, here is an example on how to use them:

```
<?php
// api/src/DataProvider/BlogPostItemDataProvider.php

namespace App\DataProvider;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use App\Entity\BlogPost;
use Doctrine\Common\Persistence\ManagerRegistry;

final class BlogPostItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
private $itemExtensions;
private $managerRegistry;

public function __construct(ManagerRegistry $managerRegistry, iterable $itemExtensions)
{
$this->managerRegistry = $managerRegistry;
$this->itemExtensions = $itemExtensions;
}

public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return BlogPost::class === $resourceClass;
}

public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?BlogPost
{
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
$repository = $manager->getRepository($resourceClass);
$queryBuilder = $repository->createQueryBuilder('o');
$queryNameGenerator = new QueryNameGenerator();
$identifiers = ['id' => $id];

foreach ($this->itemExtensions as $extension) {
$extension->applyToItem($queryBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName, $context);
if ($extension instanceof QueryResultItemExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
return $extension->getResult($queryBuilder, $resourceClass, $operationName, $context);
}
}

return $queryBuilder->getQuery()->getOneOrNullResult();
}
}

```