Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions lib/graphql/execution/batching/field_compatibility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,6 @@ def resolve_batch(frs, objects, context, kwargs)
return maybe_err
end
end
if extras.include?(:lookahead)
if kwargs.frozen?
kwargs = kwargs.dup
end
kwargs[:lookahead] = Execution::Lookahead.new(
query: context.query,
ast_nodes: frs.ast_nodes || Array(frs.ast_node),
field: self,
)
end

if extras.include?(:ast_node)
if kwargs.frozen?
kwargs = kwargs.dup
end
kwargs[:ast_node] = frs.ast_node
end

if @owner.method_defined?(@resolver_method)
results = []
Expand Down
35 changes: 30 additions & 5 deletions lib/graphql/execution/batching/field_resolve_step.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@ def self.[](_key)
end

def execute_field
query = @selections_step.query
field_name = @ast_node.name
@field_definition = @selections_step.query.get_field(@parent_type, field_name) || raise("Invariant: no field found for #{@parent_type.to_type_signature}.#{ast_node.name}")
@field_definition = query.get_field(@parent_type, field_name) || raise("Invariant: no field found for #{@parent_type.to_type_signature}.#{ast_node.name}")
objects = @selections_step.objects
if field_name == "__typename"
# TODO handle custom introspection
Expand All @@ -179,10 +180,33 @@ def execute_field
return
end

@arguments = coerce_arguments(@field_definition, @ast_node.arguments) # rubocop:disable Development/ContextIsPassedCop
if @field_definition.dynamic_introspection
objects = @selections_step.graphql_objects
end

@arguments = coerce_arguments(@field_definition, @ast_node.arguments) # rubocop:disable Development/ContextIsPassedCop
@field_definition.extras.each do |extra|
case extra
when :lookahead
if @arguments.frozen?
@arguments = @arguments.dup
end
@arguments[:lookahead] = Execution::Lookahead.new(
query: query,
ast_nodes: ast_nodes,
field: @field_definition,
)
when :ast_node
if @arguments.frozen?
@arguments = @arguments.dup
end
@arguments[:ast_node] = ast_node
else
raise ArgumentError, "This extra isn't supported yet: #{extra.inspect}. Open an issue on GraphQL-Ruby to add compatibility for it."
end
end

ctx = @selections_step.query.context
ctx = query.context

if @runner.authorization && @runner.authorizes?(@field_definition, ctx)
authorized_objects = []
Expand All @@ -198,12 +222,13 @@ def execute_field
@object_is_authorized = AlwaysAuthorized
end

ctx.query.current_trace.begin_execute_field(@field_definition, @arguments, authorized_objects, ctx.query)
query.current_trace.begin_execute_field(@field_definition, @arguments, authorized_objects, query)
@field_results = @field_definition.resolve_batch(self, authorized_objects, ctx, @arguments)
ctx.query.current_trace.end_execute_field(@field_definition, @arguments, authorized_objects, ctx.query, @field_results)
query.current_trace.end_execute_field(@field_definition, @arguments, authorized_objects, query, @field_results)

if @runner.resolves_lazies # TODO extract this
lazies = false
# TODO add a per-query cache of `.lazy?`
@field_results.each do |field_result|
if @runner.schema.lazy?(field_result)
lazies = true
Expand Down
6 changes: 5 additions & 1 deletion lib/graphql/introspection/dynamic_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
module GraphQL
module Introspection
class DynamicFields < Introspection::BaseObject
field :__typename, String, "The name of this type", null: false, dynamic_introspection: true
field :__typename, String, "The name of this type", null: false, dynamic_introspection: true, resolve_each: true

def __typename
self.class.__typename(object, context)
end

def self.__typename(object, context)
object.class.graphql_name
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/graphql/introspection/entry_points.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module GraphQL
module Introspection
class EntryPoints < Introspection::BaseObject
field :__schema, GraphQL::Schema::LateBoundType.new("__Schema"), "This GraphQL schema", null: false, dynamic_introspection: true, resolve_static: :__schema
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system", dynamic_introspection: true do
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system", dynamic_introspection: true, resolve_static: :__type do
argument :name, String
end

Expand All @@ -19,6 +19,10 @@ def __schema
end

def __type(name:)
self.class.__type(context, name: name)
end

def self.__type(context, name:)
if context.types.reachable_type?(name) && (type = context.types.type(name))
type
elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
Expand Down
3 changes: 3 additions & 0 deletions spec/graphql/authorization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class BaseInputObject < GraphQL::Schema::InputObject

class BaseField < GraphQL::Schema::Field
argument_class BaseArgument
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING

def visible?(context)
super && (context[:hide] ? @name != "hidden" : true)
end
Expand Down Expand Up @@ -351,6 +353,7 @@ class Schema < GraphQL::Schema
mutation(Mutation)
directive(Nothing)
use GraphQL::Schema::Warden if ADD_WARDEN
use GraphQL::Execution::Batching if TESTING_BATCHING
lazy_resolve(Box, :value)

def self.unauthorized_object(err)
Expand Down
1 change: 1 addition & 0 deletions spec/graphql/dataloader/async_dataloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def fiber_local_context(key:)

query(Query)
use GraphQL::Dataloader::AsyncDataloader
use GraphQL::Execution::Batching if TESTING_BATCHING
end

module AsyncDataloaderAssertions
Expand Down
31 changes: 23 additions & 8 deletions spec/graphql/dataloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,21 @@ def fetch(ids)
end
end

module Ingredient
class BaseField < GraphQL::Schema::Field
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING
end

class BaseObject < GraphQL::Schema::Object
field_class(BaseField)
end

module BaseInterface
include GraphQL::Schema::Interface
field_class(BaseField)
end

module Ingredient
include BaseInterface
field :name, String, null: false
field :id, ID, null: false

Expand All @@ -149,19 +162,19 @@ def name_by_scoped_context
end
end

class Grain < GraphQL::Schema::Object
class Grain < BaseObject
implements Ingredient
end

class LeaveningAgent < GraphQL::Schema::Object
class LeaveningAgent < BaseObject
implements Ingredient
end

class Dairy < GraphQL::Schema::Object
class Dairy < BaseObject
implements Ingredient
end

class Recipe < GraphQL::Schema::Object
class Recipe < BaseObject
def self.authorized?(obj, ctx)
ctx.dataloader.with(AuthorizedSource, ctx[:batched_calls_counter]).load(obj)
end
Expand All @@ -188,7 +201,7 @@ def slow_ingredients
end
end

class Cookbook < GraphQL::Schema::Object
class Cookbook < BaseObject
field :featured_recipe, Recipe

def self.all_featured_recipe(objects, context)
Expand All @@ -200,7 +213,7 @@ def featured_recipe
end
end

class Query < GraphQL::Schema::Object
class Query < BaseObject
field :recipes, [Recipe], null: false, resolve_static: true

def self.recipes(context)
Expand Down Expand Up @@ -456,7 +469,7 @@ def resolve
end
end

class Mutation < GraphQL::Schema::Object
class Mutation < BaseObject
field :mutation_1, mutation: Mutation1
field :mutation_2, mutation: Mutation2
field :mutation_3, mutation: Mutation3
Expand Down Expand Up @@ -484,6 +497,7 @@ def self.resolve_type(type, obj, ctx)

orphan_types(Grain, Dairy, Recipe, LeaveningAgent)
use GraphQL::Dataloader
use GraphQL::Execution::Batching if TESTING_BATCHING
lazy_resolve Proc, :call

class FieldTestError < StandardError; end
Expand Down Expand Up @@ -579,6 +593,7 @@ class Query < GraphQL::Schema::Object

query(Query)
use GraphQL::Dataloader
use GraphQL::Execution::Batching if TESTING_BATCHING
end

module DataloaderAssertions
Expand Down
28 changes: 21 additions & 7 deletions spec/graphql/execution/interpreter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@ def value
end
end

class Expansion < GraphQL::Schema::Object
class BaseField < GraphQL::Schema::Field
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING
end

class BaseObject < GraphQL::Schema::Object
field_class(BaseField)
end

module BaseInterface
include GraphQL::Schema::Interface
field_class(BaseField)
end

class Expansion < BaseObject
field :sym, String, null: false
field :lazy_sym, String, null: false
field :name, String, null: false
Expand Down Expand Up @@ -46,7 +59,7 @@ def always_cached_value
end
end

class Card < GraphQL::Schema::Object
class Card < BaseObject
field :name, String, null: false
field :colors, "[InterpreterTest::Color]", null: false
field :expansion, Expansion, null: false
Expand Down Expand Up @@ -78,7 +91,7 @@ def self.resolve_type(obj, ctx)
end
end

class FieldCounter < GraphQL::Schema::Object
class FieldCounter < BaseObject
implements GraphQL::Types::Relay::Node

field :field_counter, FieldCounter, null: false
Expand Down Expand Up @@ -139,7 +152,7 @@ def interpreter_context_for(key)
end
end

class Query < GraphQL::Schema::Object
class Query < BaseObject
# Try a root-level authorized hook that returns a lazy value
def self.authorized?(obj, ctx)
Box.new(value: true)
Expand Down Expand Up @@ -218,7 +231,7 @@ def field_counter; FieldCounter.generate_tag(context) ; end
include GraphQL::Types::Relay::HasNodeField
include GraphQL::Types::Relay::HasNodesField

class NestedQueryResult < GraphQL::Schema::Object
class NestedQueryResult < BaseObject
field :result, String
field :current_path, [String]
end
Expand All @@ -236,7 +249,7 @@ def nested_query(query:)
end
end

class Counter < GraphQL::Schema::Object
class Counter < BaseObject
field :value, Integer, null: false

def value
Expand Down Expand Up @@ -273,7 +286,7 @@ def counter
end
end

class Mutation < GraphQL::Schema::Object
class Mutation < BaseObject
field :increment_counter, Counter, null: false

def increment_counter
Expand All @@ -292,6 +305,7 @@ class Schema < GraphQL::Schema
lazy_resolve(Box, :value)
uses_raw_value(true)
use GraphQL::Schema::AlwaysVisible
use(GraphQL::Execution::Batching) if TESTING_BATCHING

def self.object_from_id(id, ctx)
OpenStruct.new(id: id)
Expand Down
Loading
Loading