New instrumentation for limiting maximum operations in a batch request#3196
Conversation
| } | ||
| if (log.isDebugEnabled()) { | ||
| log.debug("Request width info: {}", supplied_width); | ||
| } |
There was a problem hiding this comment.
Can we remove this debug log - we are moving away from logging in graphql-java (in a general sense) AND value of this log as it stands is low (eg just the wight)
| * The request width info. | ||
| */ | ||
| @PublicApi | ||
| public class RequestWidthInfo { |
There was a problem hiding this comment.
Naming is hard.
Can you justify why you called this Request Width - eg is it because the other instrumentations are request depth ?
I dont hate the name - just trying to understand the reasoning behind it
There was a problem hiding this comment.
this use case was very similar to query depth instrumentation, so I thought keeping names similar to that would be better.
|
Thanks for this PR - its been in an excellent manner with a code style that resembles our other code. We appreciate this. |
|
I am puzzled by the purpose of this PR. Here is the key code to it That is for every operation in the document, sum the size of the 1st level selection set. Now the fact is ONLY 1 operation is allowed to be executed. So this as written is confusing. It in theory is summing up selections sets that CANT be executed. They maybe redundant in a query text sense - but they wont be executed So in your tests you ONLY test for a single operation - which I guess is what you mean by "max batch operation" aka The naming here is wrong. An operation is the named query / mutation / subscription not top level fields eg the above has many aliased type level fields BUT it has only 1 operation - the implied one. So really I think this PR is about "max top level fields" - eg your aliased Is the idea really to prevent someone using aliasing (onto the same field say) from abusing aliases to create a form of pagination or some such?? As it stands right now I am struggle to understand the purpose behind this instrumentation - eg what it can be be used to stop ? |
| notThrown(Exception) | ||
| } | ||
|
|
||
| def "coercing null variables that are marked as non nullable wont blow up early"() { |
There was a problem hiding this comment.
Whats this test got to do with the code?? That validation works?
Your instrumentation kicks off at beginExecution its a garuteeed position
There was a problem hiding this comment.
Since this use case was similar to max query depth instrumentation, i tried to keep everything including the tests similar to it.
As i understand it, this test is verifying that if the input validation fails then it should return errors at the correct place(validation should fail), and the instrumentation code should not interfere with it.
|
i added description to this PR to make its purpose clear, sorry for not doing that earlier. You pointed out that only one operation is allowed to run even if user sends multiple, my code is not interfering with that flow, that behaviour is same as before, flow does not reach my code in that case. So yes, it does not make sense to loop over all definitions, if you say so I can do the check on first definition in definitions list. |
|
We want to thank you for making this PR - its well written and follows the code style of graphql-java really well However have decided not to accept it. We feel its not general purpose enough to be included in graphql-java As it stands this is a "maximum top level fields" counter. In theory one could implement this via While this PR is has some value, we dont think its valuable enough in a generic sense to be shipped with graphql-java to everyone. |
The purpose of this PR is to limit the maximum number of batch queries that user is allowed to perform in a single call. That would restrict user from sending too many queries and abusing system resources. This would allow developers to have more accurate rate limiting of their APIs.
For example,
Lets say developers have configured a rate limit on their application like: 10 API calls/second, developers would be expecting that 10 graphQL operations (queries/mutations/subscription) would be executed in one second. But if users use graphQL batching then they may send 100 operations in one request and easily avoid this limit. Using this instrumentation developers can specify max number of batch operations that user is allowed to send in one request.