spring-graphql
spring-graphql copied to clipboard
Auto-registration of max query complexity/depth instrumentations if property is set
spring-graphql
auto-configuration already supports picking Instrumentation
beans and registering them in the GraphQlSource
.
So it's just a matter of creating an instrumentation bean and it works 👍
One of the important (security) aspects to consider when developing a GraphQL server, is to make sure clients will not exhaust it by querying too many levels or fields. E.g. when having a circular model a bad client could request many many levels deep almost causing an infinite loop.
So a good practice is:
- to have a limit on the length of the GraphQL query passed to the engine itself
- to have a limit on query depth
- to have a limit on query complexity (number of fields requested)
For the latter 2 graphql-java
provides 2 instrumentation already.
I would be nice if user could enable these instrumentation by just providing an application property like:
spring.graphql.instrumentation.max-query-complexity=200
spring.graphql.instrumentation.max-query-depth=20
The starter could then contain something like below to register the beans: (this is actually what I have now in my own application)
@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);
}
(off course better to add the instrumentation properties to the actual GraphQlProperties
class)
If interested I could create a PR for this?
Thanks for creating this issue, this is something we'd like to explore more generally. I'd like to repurpose this issue for a broader query complexity/depth support with:
- check whether we can add some instrumentation around query complexity/depth for metrics
- see if there's a need for a specific mechanism in Spring Boot or Spring for GraphQL for auto-registration/auto-detection of field complexity calculator
- optionally register the instrumentation implementations mentioned in this issue
Moving this issue back to Spring for GraphQL, as this is likely to happen in the 1.1.x line and projects should provide Observation
support directly with Micrometer 1.10.
The query complexity calculator is moving out of Instrumentation
- we should use this new infrastructure when it's available.
I found some interesting materials on graphql cost analysis
- https://arxiv.org/pdf/2009.05632.pdf
- https://ibm.github.io/graphql-specs/cost-spec.html