当使用ApiPlatform时,可以自定义搜索过滤器来实现自定义搜索逻辑。有时,使用Doctrine的andWhere
方法生成的查询会导致额外的子请求,这可能会影响性能。以下是解决这个问题的代码示例:
首先,创建一个自定义搜索过滤器类,继承自ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter
:
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use Doctrine\ORM\QueryBuilder;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class CustomSearchFilter extends AbstractContextAwareFilter
{
private $logger;
public function __construct(RequestStack $requestStack, LoggerInterface $logger = null, array $properties = null)
{
parent::__construct($requestStack, $properties);
$this->logger = $logger;
}
/**
* Applies the filter on the query builder.
*
* @param QueryBuilder $queryBuilder
* @param string $property
* @param mixed|null $value
* @param string $context
*/
protected function filterProperty(QueryBuilder $queryBuilder, $property, $value, $context = null)
{
if (null === $value || !$this->isPropertyEnabled($property)) {
return;
}
$alias = $queryBuilder->getRootAliases()[0];
$field = sprintf('%s.%s', $alias, $property);
$parameterName = $this->createAlias($property);
$queryBuilder
->andWhere(sprintf('%s = :%s', $field, $parameterName))
->setParameter($parameterName, $value);
}
/**
* Gets the description of this filter for the given resource.
*
* @param string $resourceClass
* @return array
*/
public function getDescription(string $resourceClass): array
{
// Return an empty array or add some custom description for your filter
return [];
}
}
然后,在你的实体类中使用@ApiFilter
注解来应用自定义搜索过滤器:
use ApiPlatform\Core\Annotation\ApiFilter;
use App\Filter\CustomSearchFilter;
use Doctrine\ORM\Mapping as ORM;
/**
* @ApiFilter(CustomSearchFilter::class, properties={"name": "exact"})
* @ORM\Entity()
*/
class YourEntity
{
// ...
}
最后,在你的服务配置中注册自定义搜索过滤器:
services:
App\Filter\CustomSearchFilter:
autowire: true
autoconfigure: true
现在,自定义搜索过滤器将在查询构建器中使用andWhere
方法生成查询条件,而不会引发额外的子请求。
上一篇:ApiPlatform最佳方式在Graphql的变异中转换为现有实体。
下一篇:ApiPlatform:NelmioApiDoc仅在“default”部分中使用`api_platform.prefix`,而不在每个实体文档中使用。