Guides
Tutorials
The attribute can be used on a property
or on a class
.
If the attribute is given over a property, the filter will be configured on the property. For example, let's add a search filter on name
and on the prop
property of the colors
relation:
<?php
// api/src/Entity/DummyCar.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\DummyCarColor;
#[ApiResource]
class DummyCar
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
#[ORM\Column]
#[ApiFilter(SearchFilter::class, strategy: 'partial')]
public ?string $name = null;
#[ORM\OneToMany(mappedBy: "car", targetEntity: DummyCarColor::class)]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial'])]
public Collection $colors;
public function __construct()
{
$this->colors = new ArrayCollection();
}
// ...
}
<?php
// api/src/Entity/DummyCar.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Entity\DummyCarColor;
#[ApiResource]
class DummyCar
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private ?int $id = null;
#[ORM\Column]
#[ApiFilter(SearchFilter::class, strategy: 'partial')]
public ?string $name = null;
#[ORM\OneToMany(mappedBy: "car", targetEntity: DummyCarColor::class)]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial'])]
public Collection $colors;
public function __construct()
{
$this->colors = new ArrayCollection();
}
// ...
}
On the first property, name
, it's straightforward. The first attribute argument is the filter class, the second specifies options, here, the strategy:
#[ApiFilter(SearchFilter::class, strategy: 'partial')]
#[ApiFilter(SearchFilter::class, strategy: 'partial')]
In the second attribute, we specify properties
on which the filter should apply. It's necessary here because we don't want to filter colors
but the prop
property of the colors
association.
Note that for each given property we specify the strategy:
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial'])]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial'])]
The ApiFilter
attribute can be set on the class as well. If you don't specify any properties, it'll act on every property of the class.
For example, let's define three data filters (DateFilter
, SearchFilter
and BooleanFilter
) and two serialization filters (PropertyFilter
and GroupFilter
) on our DummyCar
class:
<?php
// api/src/Entity/DummyCar.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Serializer\Filter\GroupFilter;
use ApiPlatform\Serializer\Filter\PropertyFilter;
use Doctrine\ORM\Mapping as ORM;
#[ApiResource]
#[ApiFilter(BooleanFilter::class)]
#[ApiFilter(DateFilter::class, strategy: DateFilter::EXCLUDE_NULL)]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial', 'name' => 'partial'])]
#[ApiFilter(PropertyFilter::class, arguments: ['parameterName' => 'foobar'])]
#[ApiFilter(GroupFilter::class, arguments: ['parameterName' => 'foobargroups'])]
class DummyCar
{
// ...
}
<?php
// api/src/Entity/DummyCar.php
namespace App\Entity;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
use ApiPlatform\Doctrine\Orm\Filter\DateFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Serializer\Filter\GroupFilter;
use ApiPlatform\Serializer\Filter\PropertyFilter;
use Doctrine\ORM\Mapping as ORM;
#[ApiResource]
#[ApiFilter(BooleanFilter::class)]
#[ApiFilter(DateFilter::class, strategy: DateFilter::EXCLUDE_NULL)]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial', 'name' => 'partial'])]
#[ApiFilter(PropertyFilter::class, arguments: ['parameterName' => 'foobar'])]
#[ApiFilter(GroupFilter::class, arguments: ['parameterName' => 'foobargroups'])]
class DummyCar
{
// ...
}
The BooleanFilter
is applied to every Boolean
property of the class. Indeed, in each core filter we check the Doctrine type. It's written only by using the filter class:
#[ApiFilter(BooleanFilter::class)]
#[ApiFilter(BooleanFilter::class)]
The DateFilter
given here will be applied to every Date
property of the DummyCar
class with the DateFilter::EXCLUDE_NULL
strategy:
#[ApiFilter(DateFilter::class, strategy: DateFilter::EXCLUDE_NULL)]
#[ApiFilter(DateFilter::class, strategy: DateFilter::EXCLUDE_NULL)]
The SearchFilter
here adds properties. The result is the exact same as the example with attributes on properties:
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial', 'name' => 'partial'])]
#[ApiFilter(SearchFilter::class, properties: ['colors.prop' => 'ipartial', 'name' => 'partial'])]
Note that you can specify the properties
argument on every filter.
The next filters are not related to how the data is fetched but rather to how the serialization is done on those. We can give an arguments
option (see here for the available arguments):
#[ApiFilter(PropertyFilter::class, arguments: ['parameterName' => 'foobar'])]
#[ApiFilter(GroupFilter::class, arguments: ['parameterName' => 'foobargroups'])]
#[ApiFilter(PropertyFilter::class, arguments: ['parameterName' => 'foobar'])]
#[ApiFilter(GroupFilter::class, arguments: ['parameterName' => 'foobargroups'])]