Skip to content

Commit 7ca7939

Browse files
author
abluchet
committed
Document injection of tagged extensions
1 parent e57230d commit 7ca7939

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

core/data-providers.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,78 @@ final class BlogPostItemDataProvider implements ItemDataProviderInterface, Seria
161161
}
162162
}
163163
```
164+
165+
## Injecting Extensions (Pagination, Filter, EagerLoading etc.)
166+
167+
ApiPlatform provides a few extensions that you can reuse in your custom DataProvider.
168+
Note that there are a few kind of extensions which are detailed in [their own chapter of the documentation](extensions.md).
169+
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):
170+
171+
```yaml
172+
services:
173+
'App\DataProvider\BlogPostItemDataProvider':
174+
arguments:
175+
$itemExtensions: !tagged api_platform.doctrine.orm.query_extension.item
176+
```
177+
178+
Or in XML:
179+
180+
```xml
181+
<services>
182+
<service id="App\DataProvider\BlogPostItemDataProvider">
183+
<argument key="$itemExtensions" type="tagged" tag="api_platform.doctrine.orm.query_extension.item" />
184+
</service>
185+
</services>
186+
```
187+
188+
Your data provider will now have access to the core extensions, here is an example on how to use them:
189+
190+
```
191+
<?php
192+
// api/src/DataProvider/BlogPostItemDataProvider.php
193+
194+
namespace App\DataProvider;
195+
196+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
197+
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
198+
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
199+
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
200+
use App\Entity\BlogPost;
201+
use Doctrine\Common\Persistence\ManagerRegistry;
202+
203+
final class BlogPostItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
204+
{
205+
private $itemExtensions;
206+
private $managerRegistry;
207+
208+
public function __construct(ManagerRegistry $managerRegistry, iterable $itemExtensions)
209+
{
210+
$this->managerRegistry = $managerRegistry;
211+
$this->itemExtensions = $itemExtensions;
212+
}
213+
214+
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
215+
{
216+
return BlogPost::class === $resourceClass;
217+
}
218+
219+
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?BlogPost
220+
{
221+
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
222+
$repository = $manager->getRepository($resourceClass);
223+
$queryBuilder = $repository->createQueryBuilder('o');
224+
$queryNameGenerator = new QueryNameGenerator();
225+
$identifiers = ['id' => $id];
226+
227+
foreach ($this->itemExtensions as $extension) {
228+
$extension->applyToItem($queryBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName, $context);
229+
if ($extension instanceof QueryResultItemExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
230+
return $extension->getResult($queryBuilder, $resourceClass, $operationName, $context);
231+
}
232+
}
233+
234+
return $queryBuilder->getQuery()->getOneOrNullResult();
235+
}
236+
}
237+
238+
```

0 commit comments

Comments
 (0)