class GraphQL::Analysis::QueryComplexity
Calculate the complexity of a query, using {Field#complexity} values.
@example Log the complexity of incoming queries
MySchema.query_analyzers << GraphQL::Analysis::QueryComplexity.new do |query, complexity| Rails.logger.info("Complexity: #{complexity}") end
Public Class Methods
new(&block)
click to toggle source
@yield [query, complexity] Called for each query analyzed by the schema, before executing it @yieldparam query [GraphQL::Query] The query that was analyzed @yieldparam complexity [Numeric] The complexity for this query
# File lib/graphql/analysis/query_complexity.rb, line 15 def initialize(&block) @complexity_handler = block end
Public Instance Methods
call(memo, visit_type, irep_node)
click to toggle source
Implement the query analyzer API
# File lib/graphql/analysis/query_complexity.rb, line 30 def call(memo, visit_type, irep_node) if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field) if visit_type == :enter memo[:complexities_on_type].push(TypeComplexity.new) else type_complexities = memo[:complexities_on_type].pop child_complexity = type_complexities.max_possible_complexity own_complexity = get_complexity(irep_node, child_complexity) memo[:complexities_on_type].last.merge(irep_node.owner_type, own_complexity) end end memo end
final_value(reduced_value)
click to toggle source
Send the query and complexity to the block @return [Object, GraphQL::AnalysisError] Whatever the handler returns
# File lib/graphql/analysis/query_complexity.rb, line 46 def final_value(reduced_value) total_complexity = reduced_value[:complexities_on_type].last.max_possible_complexity @complexity_handler.call(reduced_value[:target], total_complexity) end
initial_value(target)
click to toggle source
State for the query complexity calcuation:
-
`target` is passed to handler
-
`complexities_on_type` holds complexity scores for each type in an IRep node
# File lib/graphql/analysis/query_complexity.rb, line 22 def initial_value(target) { target: target, complexities_on_type: [TypeComplexity.new], } end
Private Instance Methods
get_complexity(irep_node, child_complexity)
click to toggle source
Get a complexity value for a field, by getting the number or calling its proc
# File lib/graphql/analysis/query_complexity.rb, line 55 def get_complexity(irep_node, child_complexity) field_defn = irep_node.definition defined_complexity = field_defn.complexity case defined_complexity when Proc defined_complexity.call(irep_node.query.context, irep_node.arguments, child_complexity) when Numeric defined_complexity + (child_complexity || 0) else raise("Invalid complexity: #{defined_complexity.inspect} on #{field_defn.name}") end end