-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Automatic query complexity * Fix tests after master merge * Code style * Add annotation reference and add some tests * Fix PHPStan fails * Fix PHPUnit test on prefer-lowest * Fix docs generation
- Loading branch information
1 parent
96c323a
commit d286d55
Showing
21 changed files
with
1,194 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace TheCodingMachine\GraphQLite\Annotations; | ||
|
||
use Attribute; | ||
|
||
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_METHOD)] | ||
class Cost implements MiddlewareAnnotationInterface | ||
{ | ||
/** | ||
* @param int $complexity Complexity for that field | ||
* @param string[] $multipliers Names of fields by value of which complexity will be multiplied | ||
* @param ?int $defaultMultiplier Default multiplier value if all multipliers are missing/null | ||
*/ | ||
public function __construct( | ||
public readonly int $complexity = 1, | ||
public readonly array $multipliers = [], | ||
public readonly int|null $defaultMultiplier = null, | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace TheCodingMachine\GraphQLite\Middlewares; | ||
|
||
use GraphQL\Type\Definition\FieldDefinition; | ||
use TheCodingMachine\GraphQLite\Annotations\Cost; | ||
use TheCodingMachine\GraphQLite\QueryFieldDescriptor; | ||
|
||
use function implode; | ||
use function is_int; | ||
|
||
/** | ||
* Reference implementation: https://github.com/ChilliCream/graphql-platform/blob/388f5c988bbb806e46e2315f1844ea5bb63096f2/src/HotChocolate/Core/src/Execution/Options/ComplexityAnalyzerSettings.cs#L58 | ||
*/ | ||
class CostFieldMiddleware implements FieldMiddlewareInterface | ||
{ | ||
public function process(QueryFieldDescriptor $queryFieldDescriptor, FieldHandlerInterface $fieldHandler): FieldDefinition|null | ||
{ | ||
$costAttribute = $queryFieldDescriptor->getMiddlewareAnnotations()->getAnnotationByType(Cost::class); | ||
|
||
if (! $costAttribute) { | ||
return $fieldHandler->handle($queryFieldDescriptor); | ||
} | ||
|
||
$field = $fieldHandler->handle( | ||
$queryFieldDescriptor->withAddedCommentLines($this->buildQueryComment($costAttribute)), | ||
); | ||
|
||
if (! $field) { | ||
return $field; | ||
} | ||
|
||
$field->complexityFn = static function (int $childrenComplexity, array $fieldArguments) use ($costAttribute): int { | ||
if (! $costAttribute->multipliers) { | ||
return $costAttribute->complexity + $childrenComplexity; | ||
} | ||
|
||
$cost = $costAttribute->complexity + $childrenComplexity; | ||
$needsDefaultMultiplier = true; | ||
|
||
foreach ($costAttribute->multipliers as $multiplier) { | ||
$value = $fieldArguments[$multiplier] ?? null; | ||
|
||
if (! is_int($value)) { | ||
continue; | ||
} | ||
|
||
$cost *= $value; | ||
$needsDefaultMultiplier = false; | ||
} | ||
|
||
if ($needsDefaultMultiplier && $costAttribute->defaultMultiplier !== null) { | ||
$cost *= $costAttribute->defaultMultiplier; | ||
} | ||
|
||
return $cost; | ||
}; | ||
|
||
return $field; | ||
} | ||
|
||
private function buildQueryComment(Cost $costAttribute): string | ||
{ | ||
return 'Cost: ' . | ||
implode(', ', [ | ||
'complexity = ' . $costAttribute->complexity, | ||
'multipliers = [' . implode(', ', $costAttribute->multipliers) . ']', | ||
'defaultMultiplier = ' . ($costAttribute->defaultMultiplier ?? 'null'), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.