Skip to content

Commit

Permalink
feat(Context#skip) add API for skipping fields from user code
Browse files Browse the repository at this point in the history
  • Loading branch information
rmosolgo committed Apr 21, 2017
1 parent e28cb0c commit f4500fd
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
17 changes: 10 additions & 7 deletions lib/graphql/execution/execute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ module Execution
# A valid execution strategy
# @api private
class Execute
PROPAGATE_NULL = :__graphql_propagate_null__
# @api private
SKIP = Object.new
# @api private
PROPAGATE_NULL = Object.new

def execute(ast_operation, root_type, query)
result = resolve_selection(
Expand All @@ -25,14 +28,8 @@ def execute(ast_operation, root_type, query)

def resolve_selection(object, current_type, selection, query_ctx, mutation: false, subscription_update: false)
selection_result = SelectionResult.new
query = query_ctx.query

selection.typed_children[current_type].each do |name, subselection|
# Can't `break` because technically multiple fields could match
if subscription_update && query.subscription_key != subselection.subscription_key
next
end

field_result = resolve_field(
selection_result,
subselection,
Expand All @@ -42,6 +39,10 @@ def resolve_selection(object, current_type, selection, query_ctx, mutation: fals
query_ctx
)

if field_result == SKIP
next
end

if mutation
GraphQL::Execution::Lazy.resolve(field_result)
end
Expand Down Expand Up @@ -145,6 +146,8 @@ def resolve_value(owner, parent_type, field_defn, field_type, value, selection,
else
nil
end
elsif value == SKIP
value
else
case field_type.kind
when GraphQL::TypeKinds::SCALAR
Expand Down
9 changes: 8 additions & 1 deletion lib/graphql/query/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ def spawn(key:, selection:, parent_type:, field:)
)
end

# Return this value to tell the runtime
# to exclude this field from the response altogether
def skip
GraphQL::Execution::Execute::SKIP
end

class FieldResolutionContext
extend Forwardable

Expand All @@ -87,7 +93,8 @@ def initialize(context:, path:, selection:, field:, parent_type:)
def_delegators :@context,
:[], :[]=, :to_h, :key?, :fetch,
:spawn, :query, :schema,
:warden, :errors, :execution_strategy, :strategy
:warden, :errors, :execution_strategy, :strategy,
:skip

# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
def ast_node
Expand Down
6 changes: 2 additions & 4 deletions lib/graphql/subscriptions/instrumentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ def call(obj, args, ctx)
# The root object is _already_ the subscription update:
obj
else
# It should only:
# - Register the selection (first condition)
# - Pass `obj` to the child selection (second condition)
raise "An unselected subscription field should never be called"
# This is a subscription update, but this event wasn't triggered.
ctx.skip
end
end
end
Expand Down

0 comments on commit f4500fd

Please sign in to comment.