With `QueryParameter`, it is not possible to set multiple filters for the same property
API Platform version(s) affected: 4.2.2
Description
As the document warns, ApiFilter is currently deprecated and using QueryParameter is recommended.
However, there are several bugs when applying filters using QueryParameter.
- With
QueryParameter, it is not possible to set multiple filters for the same property ExistsFilterandOrderFilteroutput incorrect parameter names to Hydra'ssearchproperty (Symfony only):propertykey cannot be used inSearchFilter(Symfony only)
With QueryParameter, it is not possible to set multiple filters for the same property
For example, if we want to apply both NumericFilter and RangeFilter to the id property, we can achieve this with ApiFilter as follows:
#[ApiFilter(NumericFilter::class, properties: ['id'])]
#[ApiFilter(RangeFilter::class, properties: ['id'])]
This will output the following parameters in OpenAPI, and these parameters will actually function correctly.
On the other hand, when using QueryParameter, we need to write it like this: (The key must be the same as the actual property name.)
#[QueryParameter(key: 'id', filter: 'serviceId.for.numeric_filter')]
#[QueryParameter(key: 'id', filter: 'serviceId.for.range_filter')]
However, if we define multiple QueryParameters with the same key like this, the later definition overwrites the earlier one, so in this case, the NumericFilter will not work. The OpenAPI output will be as follows:
Note
Although writing it like this should be equivalent, currently there is a bug (#7492) where duplicate keys are only allowed when using the
parametersargument, so in this case, theNumericFilterhappens to work.#[ApiResource( parameters: [ new QueryParameter(key: 'id', filter: 'serviceId.for.numeric_filter'), new QueryParameter(key: 'id', filter: 'serviceId.for.range_filter'), ], )]However, this is not the intended behavior.
@dlubitz Please refer to the FreeTextQueryFilter documentation which allows filtering allows you to apply a single filter across a list of properties.
@vinceAmstoutz Thank you for your comment. But I don't want to "apply one filter to multiple properties"; rather, I want to "apply multiple filters to the same property".
Hi @ttskch, apologies, I read your previous comment too quickly. For the Symfony variant you should replace key by property, as follows: new QueryParameter(property: 'id', filter: 'serviceId.for.numeric_filter'),.
Could you please confirm if the following configuration works? I'm curious if API Platform can handle two QueryParameter attributes targeting the same property ('id') without explicit array keys:
#[ApiResource(parameters: [
new QueryParameter(property: 'id', filter: 'serviceId.for.numeric_filter'),
new QueryParameter(property: 'id', filter: 'serviceId.for.range_filter'),
])]
My suspicion is that you might need to provide unique array keys for each QueryParameter when targeting the same property, as shown below:
#[ApiResource(parameters: [
'idNumeric' => new QueryParameter(property: 'id', filter: 'serviceId.for.numeric_filter'),
'idRange' =>new QueryParameter(property: 'id', filter: 'serviceId.for.range_filter'),
])]
I'm not certain if this is required, but it seems like a more explicit way to define multiple filters on the same property.
Would you be able to test this and let me know if the first approach works, or if the second one (with explicit keys) is necessary?
@vinceAmstoutz
Thank you for your advice!
I tried it, and the second approach worked perfectly! (The first one resulted in an error because the key was undefined.)
Below is the reproducer.
- https://github.com/ttskch/api-platform-core-7493
- https://github.com/ttskch/api-platform-core-7493/commit/57d2c7bc29fda3c5691e084cbb8c02b6c4148d49
- https://github.com/ttskch/api-platform-core-7493/commit/d825f5150c637de95249d95f4d65ae781def3d30
As you say, it's a reasonable specification that we need to explicitly set different keys while specifying the same property in the property field.
Although documentation is needed because what was possible with ApiFilter is no longer possible with QueryParameter, I think it is safe to conclude that this is not a bug.