Collection Data Provider를 생성하고 Doctrine Extension, Filters 및 Pagination을 유지하는 방법 [Api Platform]
18734 단어 phpapiplatformsymfonyapi
전체 프로젝트를 만들지는 않겠지만 내 저장소로 이동하여 고정물이 있는 프로젝트에서 공급자를 볼 수 있습니다.
이것은 저장소https://github.com/aratinau/api-platform-pagination의 홈페이지입니다(API 플랫폼을 사용하여 사용자 정의 데이터로 페이지 매김을 생성하기 위해 여러 다른 예제를 보여줍니다).
여기에서 병합 요청을 볼 수 있습니다: https://github.com/aratinau/api-platform-pagination/commit/1d27f16adecda1c0956fcc5d0da81f017d915c1b
매개변수
includeArchived
가 누락된 경우 보관되지 않은 책만 반환하는 제공자를 만들 것입니다. 매개변수가 includeArchived=true
인 경우 모든 책(아카이브 여부)그런 다음 정의된 로케일로 책만 반환하는 Doctrine Extension을 만듭니다.
이것은 우리의 책 엔티티
src/Entity/Book.php
입니다.<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\BookRepository;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
/**
* @ApiResource()
* @ApiFilter(OrderFilter::class)
* @ORM\Entity(repositoryClass=BookRepository::class)
*/
class Book
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
/**
* @ORM\Column(type="boolean")
*/
private $isArchived;
/**
* @ORM\Column(type="string", length=4)
*/
private $locale;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getIsArchived(): ?bool
{
return $this->isArchived;
}
public function setIsArchived(bool $isArchived): self
{
$this->isArchived = $isArchived;
return $this;
}
public function getLocale(): ?string
{
return $this->locale;
}
public function setLocale(string $locale): self
{
$this->locale = $locale;
return $this;
}
}
만들기
src/DataProvider/BookCollectionDataProvider.php
<?php
namespace App\DataProvider;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
use App\DTO\SessionParameter;
use App\Entity\Book;
use App\Entity\Session;
use Doctrine\Persistence\ManagerRegistry;
class BookCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
public function __construct(
private ManagerRegistry $managerRegistry,
private $collectionExtensions,
) {
}
public function getCollection(
string $resourceClass,
string $operationName = null,
array $context = []
): iterable {
// here we define to false when the param 'includeArchived' is missing (by default)
$includeArchived = $context['filters']['includeArchived'] ?? 'false';
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
$repository = $manager->getRepository($resourceClass);
$queryBuilder = $repository->createQueryBuilder('o');
$alias = $queryBuilder->getRootAliases()[0];
// by default we want only books not archived
if ($includeArchived === 'false') {
$queryBuilder->andWhere("$alias.isArchived = false");
}
/*
Then we will add to all extensions our queryBuilder updated.
We could inject only the extension we needs but I wanted to show them all to you.
The first extension (BookExtension) will be created after
*/
$queryNameGenerator = new QueryNameGenerator();
foreach ($this->collectionExtensions as $extension) {
/*
* Extensions are (in this order)
* - "App\Doctrine\BookExtension"
* - "ApiPlatform\Doctrine\Orm\Extension\FilterExtension"
* - "ApiPlatform\Doctrine\Orm\Extension\FilterEagerLoadingExtension"
* - "ApiPlatform\Doctrine\Orm\Extension\EagerLoadingExtension"
* - "ApiPlatform\Doctrine\Orm\Extension\OrderExtension"
* - "ApiPlatform\Doctrine\Orm\Extension\PaginationExtension"
*/
$extension->applyToCollection(
$queryBuilder,
$queryNameGenerator,
$resourceClass,
$operationName,
$context
);
/*
This next condition check if we have the pagination activated (by default is yes) and the result is returned
*/
if (
$extension instanceof QueryResultCollectionExtensionInterface
&&
$extension->supportsResult($resourceClass, $operationName, $context)
) {
return $extension->getResult($queryBuilder, $resourceClass, $operationName, $context);
}
}
// we are here only if we have deactivate the pagination
return $queryBuilder->getQuery()->getResult();
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Book::class === $resourceClass;
}
}
$collectionExtensions
를 삽입하려면 config/services.yaml
를 추가해야 합니다.App\DataProvider\BookCollectionDataProvider:
bind:
$collectionExtensions: !tagged api_platform.doctrine.orm.query_extension.collection
이제 파일을 생성합니다
src/Doctrine/BookExtension.php
.<?php
namespace App\Doctrine;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use App\Entity\Book;
use Doctrine\ORM\QueryBuilder;
class BookExtension implements QueryCollectionExtensionInterface
{
private const LOCALE = 'fr';
public function applyToCollection(
QueryBuilder $queryBuilder,
$queryNameGenerator,
string $resourceClass,
string $operationName = null
) {
/*
We ask to return only the book with the locale 'fr'
*/
if ($resourceClass === Book::class) {
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder
->andWhere("$rootAlias.locale = :locale")
->setParameter('locale', self::LOCALE)
;
}
}
}
이제
Book
엔터티 필터(예: OrderFilter
)를 추가하고 컬렉션 공급자를 통해 필터링된 컬렉션을 유지할 수 있습니다.GET
/books
보관되지 않은 책을 반환합니다.GET
/books?includeArchived=false
보관되지 않은 책을 반환합니다.GET
/books?includeArchived=true
은 모든 책을 반환합니다.당신이 좋아 바랍니다! 🙂🚀
Reference
이 문제에 관하여(Collection Data Provider를 생성하고 Doctrine Extension, Filters 및 Pagination을 유지하는 방법 [Api Platform]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aratinau/how-to-create-a-collection-data-provider-and-keep-doctrine-extension-filters-and-pagination-on-it-api-platform-59ih텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)