spring-graphql icon indicating copy to clipboard operation
spring-graphql copied to clipboard

How to create instrumentationf for maxQueries can be executed in single request?

Open vrubal opened this issue 3 years ago • 6 comments

To add the maxQueryComplexity and maxQueryDepth instrumentation are available, which can be configured as follows. Is there any way to create a custom instrumentation to for maxQueries 

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.graphql.instrumentation", name = "max-query-complexity")
public MaxQueryComplexityInstrumentation maxQueryComplexityInstrumentation(@Value("${spring.graphql.instrumentation.max-query-complexity}") int maxComplexity) {
    return new MaxQueryComplexityInstrumentation(maxComplexity);
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.graphql.instrumentation", name = "max-query-depth")
public MaxQueryDepthInstrumentation maxQueryDepthInstrumentation(@Value("${spring.graphql.instrumentation.max-query-depth}") int maxDepth) {
    return new MaxQueryDepthInstrumentation(maxDepth);
}

vrubal avatar Aug 19 '22 13:08 vrubal

I don't understand - could explain what you're trying to achieve here and why this code sample doesn't work for you?

bclozel avatar Aug 19 '22 13:08 bclozel

No issue with this instrumentation. I'm able to validate queryDepth and queryComplexity with this instrumentation. My requirement is to add instrumentation for number of queries in single request. Trying to restrict user to requesting all available queries at once. User should be allowed to run upto N number of queries in single API request.

vrubal avatar Aug 19 '22 14:08 vrubal

I think that's more or less what the query complexity does, at the field level. In my mind, GraphQL Java considers that the cost should be calculated in general when fetching data, not necessarily at the root of a query. You can provide your own FieldComplexityCalculator to the MaxQueryComplexityInstrumentation to have something specific.

If you really want to limit the number of queries overall, I think you might need to implement a custom SimpleInstrumentation. Maybe the GraphQL Java community has a different approach for that? Did you ask the community about this?

In the context of Spring for GraphQL, I don't think all @SchemaMapping are equal, as fetching from a local cache, a database or a remote service don't have the same cost. We could provide a (annotation-based, or functional) mechanism to automatically associate a complexity value with a controller method. We would then collect all that information while mappings are being parsed and reuse that information with a custom Instrumentation. I think this is where #469 is headed.

bclozel avatar Aug 19 '22 14:08 bclozel

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues avatar Aug 26 '22 14:08 spring-projects-issues

Asked question here in graphql-java community, https://github.com/graphql-java/graphql-java/discussions/2937 As @bclozel suggested would require to have a cutom implementation by extending the SimpleInstrumentation.

vrubal avatar Aug 27 '22 17:08 vrubal

I've implementated the custom instrumentation as below:

public class MaxQueryCountInstrumentation extends SimpleInstrumentation {

   private int maxQueryCount;
   public MaxQueryCountInstrumentation(int maxqueryCount) {
        this.maxQueryCount=maxqueryCount;
    }


    @Override
    public InstrumentationContext<ExecutionResult> beginExecuteOperation(InstrumentationExecuteOperationParameters parameters) {
        int size = ((OperationDefinition) parameters.getExecutionContext().getDocument().getDefinitions().get(0)).getSelectionSet().getSelections().size();
        if (maxQueryCount < size)
            throw new AbortExecutionException("Maximum query count exceeded " + size + " > " + maxQueryCount);
        return SimpleInstrumentationContext.noOp();
    }

}

vrubal avatar Aug 30 '22 17:08 vrubal