summaryrefslogtreecommitdiff
path: root/app/graphql/types/base_field.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/graphql/types/base_field.rb')
-rw-r--r--app/graphql/types/base_field.rb34
1 files changed, 32 insertions, 2 deletions
diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb
index 8c8b8a82d3e..15331129134 100644
--- a/app/graphql/types/base_field.rb
+++ b/app/graphql/types/base_field.rb
@@ -7,10 +7,40 @@ module Types
DEFAULT_COMPLEXITY = 1
def initialize(*args, **kwargs, &block)
- # complexity is already defaulted to 1, but let's make it explicit
- kwargs[:complexity] ||= DEFAULT_COMPLEXITY
+ kwargs[:complexity] ||= field_complexity(kwargs[:resolver_class])
super(*args, **kwargs, &block)
end
+
+ private
+
+ def field_complexity(resolver_class)
+ if resolver_class
+ field_resolver_complexity
+ else
+ DEFAULT_COMPLEXITY
+ end
+ end
+
+ def field_resolver_complexity
+ # Complexity can be either integer or proc. If proc is used then it's
+ # called when computing a query complexity and context and query
+ # arguments are available for computing complexity. For resolvers we use
+ # proc because we set complexity depending on arguments and number of
+ # items which can be loaded.
+ proc do |ctx, args, child_complexity|
+ page_size = @max_page_size || ctx.schema.default_max_page_size
+ limit_value = [args[:first], args[:last], page_size].compact.min
+
+ # Resolvers may add extra complexity depending on used arguments
+ complexity = child_complexity + self.resolver&.try(:resolver_complexity, args).to_i
+
+ # Resolvers may add extra complexity depending on number of items being loaded.
+ multiplier = self.resolver&.try(:complexity_multiplier, args).to_f
+ complexity += complexity * limit_value * multiplier
+
+ complexity.to_i
+ end
+ end
end
end