-
-
Notifications
You must be signed in to change notification settings - Fork 570
Fix query complexity for fragments defined after operations #1826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| foreach ($document->definitions as $definition) { | ||
| if (! $definition instanceof OperationDefinitionNode) { | ||
| continue; | ||
| } | ||
|
|
||
| $this->queryComplexity = $this->fieldComplexity($definition->selectionSet); | ||
|
|
||
| if ($this->queryComplexity > $this->maxQueryComplexity) { | ||
| $context->reportError( | ||
| new Error(static::maxQueryComplexityErrorMessage( | ||
| $this->maxQueryComplexity, | ||
| $this->queryComplexity | ||
| )) | ||
| ); | ||
| return; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part does look weird, but it matches the previous behaviour when a query contains multiple operations:
- complexity for all operations is computed
$this->queryComplexitycontains complexity of the first operation exceeding the limit.
query A {
potato
}
query B {
tomato
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's document this status quo by covering it with tests and maybe a comment to the property. It does seem weird and non-ideal though, sow could we change this in a future major version where we allow breaking changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test for the current behaviour 0f2926f
The validator could be changed to only validate the operation being run; but thats a separate issue and outside the scope of this PR
When NodeKind::OPERATION_DEFINITION visitor is run, selection sets for later-defined fragments have not yet been colected by NodeKind::SELECTION_SET visitor. Using NodeKind::DOCUMENT visitor instead, guarantees all selection sets have been collected.
312dd0d to
a2bb2ee
Compare
Fixes #785, test shamelessly taken from #1350
QueryComplexitycollects all field nodes and their definitions using aNodeKind::SELECTION_SETvisitor. WhenNodeKind::OPERATION_DEFINITIONvisitor was run, complexity function, on the field's definition, for each found field was executed.However, that's not enough when using fragments. When
NodeKind::OPERATION_DEFINITIONis run, field definitions for later-defined fragments have not yet been collected:Complexity function for non-collected fields (
aandb, in this case) was not run, and a fallback of value1was always used instead.This PR changes
QueryComplexityto use aNodeKind::DOCUMENTvisitor in place ofNodeKind::OPERATION_DEFINITION, as by then it's guaranteed all selection sets have been visited, and field definitions collected.There is a minor behaviour change with this - when query complexity is exceeded, an error will now be thrown later during validation than before. As error order is not part of the api contract, I assume this is acceptable.