Class: Tina4::GraphQLExecutor
- Inherits:
-
Object
- Object
- Tina4::GraphQLExecutor
- Defined in:
- lib/tina4/graphql.rb
Overview
─── Executor ─────────────────────────────────────────────────────────
Instance Attribute Summary collapse
-
#max_depth ⇒ Object
max_depth bounds selection-set nesting (DoS / stack-overflow guard).
Instance Method Summary collapse
- #execute(document, variables: {}, context: {}, operation_name: nil) ⇒ Object
-
#initialize(schema, max_depth: 50) ⇒ GraphQLExecutor
constructor
A new instance of GraphQLExecutor.
Constructor Details
#initialize(schema, max_depth: 50) ⇒ GraphQLExecutor
Returns a new instance of GraphQLExecutor.
603 604 605 606 |
# File 'lib/tina4/graphql.rb', line 603 def initialize(schema, max_depth: 50) @schema = schema @max_depth = max_depth end |
Instance Attribute Details
#max_depth ⇒ Object
max_depth bounds selection-set nesting (DoS / stack-overflow guard). Threaded down from the owning GraphQL instance; <= 0 disables the guard.
601 602 603 |
# File 'lib/tina4/graphql.rb', line 601 def max_depth @max_depth end |
Instance Method Details
#execute(document, variables: {}, context: {}, operation_name: nil) ⇒ Object
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/tina4/graphql.rb', line 608 def execute(document, variables: {}, context: {}, operation_name: nil) # Collect fragments fragments = {} operations = [] document[:definitions].each do |defn| case defn[:kind] when :fragment fragments[defn[:name]] = defn when :operation operations << defn end end # Pick the operation operation = if operation_name operations.find { |op| op[:name] == operation_name } elsif operations.length == 1 operations.first else raise GraphQLError, "Must provide operation name when multiple operations exist" end raise GraphQLError, "Unknown operation: #{operation_name}" unless operation # Resolve variables resolved_vars = resolve_variables(operation[:variables], variables) # Choose root fields root_fields = case operation[:operation] when :query then @schema.queries when :mutation then @schema.mutations else raise GraphQLError, "Unsupported operation: #{operation[:operation]}" end # Execute selection set data = {} errors = [] # Top-level selections start at depth 1. Depth is incremented on every # recursive entry (sub-selections, fragment spreads, inline fragments) so # an over-deep query OR a circular fragment is caught before the # interpreter stack overflows. operation[:selection_set].each do |selection| resolve_selection(selection, root_fields, nil, resolved_vars, context, fragments, data, errors, 1) end result = { "data" => data } result["errors"] = errors unless errors.empty? result end |