Description
API Platform version(s) affected: 2.5.4
Description
In my context, i need to enable both RangeFilter and NumericFilter on the same property to have the following filtering option : less than, equals, between and greater than
In such case, the graphql schema will convert both filters in the same way using the property name to identify the filter.
In the following example
/**
* @ApiResource()
* @ApiFilter(RangeFilter::class, properties={"age"})
* @ApiFilter(NumericFilter::class, properties={"age"})
*/
class Dummy
{
/** @var int $age */
private $age;
// ...
}
The REST collection endpoint enables both filters with the syntax /dummies?age=18
and /dummies?age[gt]=18
But the GraphQL endpoint enables only the NumericFilter
with the syntax dummies(age: "18") { ... }
(as the RangeFilter
uses the syntax dummies(age: {gt: "18"})
)
How to reproduce
Here a valid entity declaration
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\RangeFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\NumericFilter;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Dummy
* @package App\Entity
*
* @ApiResource(
* graphql={
* "item_query",
* "collection_query"
* }
* )
* @ApiFilter(RangeFilter::class, properties={"age"})
* @ApiFilter(NumericFilter::class, properties={"age"})
* @ORM\Entity
*/
class Dummy
{
/**
* @var string|null
* @ApiProperty(iri="http://schema.org/identifier")
* @ORM\Column(type="guid")
* @ORM\GeneratedValue(strategy="UUID")
* @ORM\Id()
*/
private $id;
public function getId()
{
return $this->id;
}
public function setId($id): void
{
$this->id = $id;
}
/**
* @var integer
* @ApiProperty
* @ORM\Column(type="integer")
*/
private $age;
public function getAge()
{
return $this->age;
}
public function setAge($age): void
{
$this->age = $age;
}
}
Case 1. Both RangeFilter and NumericFilter
In the entity definition, enabling both the RangeFilter
and the NumericFilter
the following graphql query is available
{
dummies(age: 18) {
edges {
node {
id age
}
}
}
}
And the following syntax:
{
dummies(age: {gt:"18"}) {
edges {
node {
id age
}
}
}
}
raises the error:
{
"errors": [
{
"message": "Field \"dummies\" argument \"age\" requires type Int, found {gt: \"18\"}.",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 2,
"column": 16
}
]
}
]
}
Case 2. Only RangeFilter
In the entity definition, enabling only the RangeFilter
(delete the NumericFilter
filter declaration) the following graphql query is available
{
dummies(age: {gt:"18"}) {
edges {
node {
id age
}
}
}
}
And the following syntax:
{
dummies(age: 18) {
edges {
node {
id age
}
}
}
}
raises the error:
{
"errors": [
{
"message": "Field \"dummies\" argument \"age\" requires type DummyFilter_age, found 18.",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 2,
"column": 16
}
]
}
]
}
Possible Solution
The RangeFilter should supports an eq
(and neq
) syntax allowing to use, with one filter, all the cases : less than, between, greater than and equal to
Additional Context
Note that using the NumericFilter
a numerical value should be defined but using the RangeFilter
, a string should be used to define the value.
Should I open another issue ?