1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
# frozen_string_literal: true
module GraphQL
module Analysis
# A query reducer for measuring the depth of a given query.
#
# See https://graphql-ruby.org/queries/ast_analysis.html for more examples.
#
# @example Logging the depth of a query
# class LogQueryDepth < GraphQL::Analysis::QueryDepth
# def result
# log("GraphQL query depth: #{@max_depth}")
# end
# end
#
# # In your Schema file:
#
# class MySchema < GraphQL::Schema
# query_analyzer LogQueryDepth
# end
#
# # When you run the query, the depth will get logged:
#
# Schema.execute(query_str)
# # GraphQL query depth: 8
#
module AST
class QueryDepth < Analyzer
def initialize(query)
@max_depth = 0
@current_depth = 0
@count_introspection_fields = query.schema.count_introspection_fields
super
end
def on_enter_field(node, parent, visitor)
return if visitor.skipping? ||
visitor.visiting_fragment_definition? ||
(@count_introspection_fields == false && visitor.field_definition.introspection?)
@current_depth += 1
end
def on_leave_field(node, parent, visitor)
return if visitor.skipping? ||
visitor.visiting_fragment_definition? ||
(@count_introspection_fields == false && visitor.field_definition.introspection?)
if @max_depth < @current_depth
@max_depth = @current_depth
end
@current_depth -= 1
end
def result
@max_depth
end
end
end
end
end
|