Open
Description
Description
QueryComplexity
rule implements visitor in such a way that results in missing field definitions when non-inline fragments are used and defined after the operation (as it usually is). If you reverse the order and put fragments first, all works fine.
Reproduction path
A simple reproduction script is attaching a custom complexity closure to ExampleType
fields. They are included using a fragment, and should result in a complexity error. However, no such error is triggered, because these field definitions are missing from fieldNodeAndDefs
, and a default complexity function is used on them.
<?php
use GraphQL\GraphQL;
use GraphQL\Utils\BuildSchema;
use GraphQL\Validator\Rules\QueryComplexity;
require_once __DIR__ . '/vendor/autoload.php';
$exampleSchema = '
type Query {
example: ExampleType
}
type ExampleType {
a: Int
b: String
}
';
$query = '
query {
...exampleFragment
}
fragment exampleFragment on Query { # values from default complexity fn
example { # 2 + 1
a
b
}
}
';
$typeConfigDecorator = function (array $typeConfig): array {
if ($typeConfig['name'] !== 'ExampleType') {
return $typeConfig;
}
$typeConfig['fields'] = static function () use ($typeConfig) {
$fieldDefinitions = $typeConfig['fields']();
foreach ($fieldDefinitions as $fieldName => &$fieldDefinition) {
$fieldDefinition['complexity'] = function ($childComplexity) {
return $childComplexity + 1000;
};
}
return $fieldDefinitions;
};
return $typeConfig;
};
$schema = BuildSchema::build($exampleSchema, $typeConfigDecorator);
$queryComplexity = new QueryComplexity(100);
$result = GraphQL::executeQuery(
$schema,
$query,
null,
null,
null,
null,
null,
[
$queryComplexity
]
);
echo json_encode($result->toArray(), JSON_PRETTY_PRINT);
Put it in an empty directory, call composer require webonyx/graphql-php
and run php complexity.php
.