Description
API Platform version(s) affected: 3.1.7
Description
ApiResource having Query
with default name (item_query
) and QueryCollection
with custom name will cause exception Operation "collection_query" not found for resource [...]
to be thrown. The same exception is thrown in opposite scenario ie. having QueryCollection
with default name and Query
with custom name, but then operation item_query
is not found.
How to reproduce
Create API Resource having Query
with default name and QueryCollection
with custom name:
#[ApiResource(
graphQlOperations: [
new Query(),
new QueryCollection(name: 'test'),
],
)]
or opposite scenario:
#[ApiResource(
graphQlOperations: [
new Query(name: 'test'),
new QueryCollection(),
],
)]
Possible Solution
This problem is likely caused by #5174. Possible solution would be to rollback these changes: https://github.com/api-platform/core/pull/5174/files#diff-e5ead97adcfdc734d5f4c2a5c9a12b233a20760aefb6954b16103ba382e6ea79L77-L82 or to modify method https://github.com/api-platform/core/blob/main/src/Metadata/Resource/Factory/OperationDefaultsTrait.php#L130 to the following:
private function completeGraphQlOperations(ApiResource $resource): ApiResource
{
$graphQlOperations = $resource->getGraphQlOperations();
$hasQueryOperation = false;
$hasQueryCollectionOperation = false;
foreach ($graphQlOperations as $operation) {
- if ($operation instanceof Query && !$operation instanceof QueryCollection) {
+ if ($operation instanceof Query && !$operation instanceof QueryCollection && $operation->getName() === 'item_query') {
$hasQueryOperation = true;
}
- if ($operation instanceof QueryCollection) {
+ if ($operation instanceof QueryCollection && $operation->getName() === 'collection_query') {
$hasQueryCollectionOperation = true;
}
}
if (!$hasQueryOperation) {
$queryOperation = (new Query())->withNested(true);
$graphQlOperations[$queryOperation->getName()] = $queryOperation;
}
if (!$hasQueryCollectionOperation) {
$queryCollectionOperation = (new QueryCollection())->withNested(true);
$graphQlOperations[$queryCollectionOperation->getName()] = $queryCollectionOperation;
}
return $resource->withGraphQlOperations($graphQlOperations);
}