嵌套资源的 Api 平台别名过滤器

时间:2021-01-25 09:22:49

标签: symfony api-platform.com

我目前正在使用 API 平台及其默认的 SearchFilter,它按预期工作。
但是,由于 url 中的查询字符串很长,因此对资源之间的深层关系进行过滤可能会很繁重。 (我有多个这样的实体。)

例如,我想搜索特定国家/地区商店中列出的所有书籍:

{url}/books?department.store.city.country.name=italy

有没有办法编辑@ApiFilter(SearchFilter::class, properties={}) 以便在最后得到简单的?

{url}/books?country_filter=italy

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以创建一个自定义 api 过滤器并在其中添加您自己的逻辑。将其称为 country_filter 并仅传递一个值,之后自定义查询将在数据库中搜索并返回行。要制作一个,您必须扩展 AbstractFilter 类,然后您必须将此过滤器添加到您的实体中。来自官方网站的一个很好的教程是 here 和下一章 here

答案 1 :(得分:0)

谢谢您的建议,

经过一些(数小时的)研究,我得出的结论是在创建我的个人 CountryFilter 时扩展 SearchFilter :

在我的实体类中:

/*
 * @ApiFilter(CountryFilter::class, properties={
 *   "country_filter": "department.store.city.country.name",
 * })
 */

在我的 App\Filter\CountryFilter.php 中:

<?php

namespace App\Filter;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Doctrine\ORM\QueryBuilder;

final class CountryFilter extends SearchFilter
{
    protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
    {
        foreach($this->properties as $alias => $propertyName){
            if($alias == $property){
                $property = $propertyName;
                break;
            }
        }

        /*
        if (
            null === $value ||
            !$this->isPropertyEnabled($property, $resourceClass) ||
            !$this->isPropertyMapped($property, $resourceClass, true)
        ) {
            return;
        }
        */

        // The rest of the SearchFilter.php copy/pasted code ...
    }

    public function getDescription(string $resourceClass): array
    {
        // ....
    }
}