Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Api platform aliasing filters for nested resources

I'm currently using API Platform and its default SearchFilter and it works as intended.
However, filtering on a deep relationship between resources can be heavy by its quite long query string in the url. (I have got multiple entities like this.)

For instance I want to search every books listed in the stores of a specific country :

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

Is there any way to edit the @ApiFilter(SearchFilter::class, properties={}) in order to get simply at the end ?

{url}/books?country_filter=italy

Thanks !

like image 548
Reconnois Avatar asked Oct 29 '25 22:10

Reconnois


1 Answers

Thank you for your advices,

After some (hours of) researches, I came to the conclusion to extend the SearchFilter when creating my personnal CountryFilter :

In my entity class :

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

In my 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
    {
        // ....
    }
}
like image 77
Reconnois Avatar answered Nov 01 '25 23:11

Reconnois



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!