From 3135a6e45922a3d7302d8c1653be1690c4922dec Mon Sep 17 00:00:00 2001 From: exAspArk Date: Wed, 8 Apr 2020 12:28:20 -0400 Subject: [PATCH 1/2] Fix compatibility with GraphQL Interpreter and BatchLoader.for --- lib/batch_loader/graphql.rb | 20 +++++++++++++++++--- spec/fixtures/graphql_schema.rb | 9 +++++++++ spec/graphql_spec.rb | 17 ++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/batch_loader/graphql.rb b/lib/batch_loader/graphql.rb index 27ba42e..372542b 100644 --- a/lib/batch_loader/graphql.rb +++ b/lib/batch_loader/graphql.rb @@ -4,15 +4,29 @@ class BatchLoader class GraphQL def self.use(schema_definition) schema_definition.lazy_resolve(BatchLoader::GraphQL, :sync) - # for graphql gem versions <= 1.8.6 which work with BatchLoader instead of BatchLoader::GraphQL - schema_definition.instrument(:field, self) + + # in cases when BatchLoader is being used instead of BatchLoader::GraphQL + if schema_definition.respond_to?(:interpreter?) && schema_definition.interpreter? + schema_definition.tracer(self) + else + schema_definition.instrument(:field, self) + end + end + + def self.trace(event, _data) + if event == 'execute_field' + result = yield + result.respond_to?(:__sync) ? wrap(result) : result + else + yield + end end def self.instrument(type, field) old_resolve_proc = field.resolve_proc new_resolve_proc = ->(object, arguments, context) do result = old_resolve_proc.call(object, arguments, context) - result.respond_to?(:__sync) ? BatchLoader::GraphQL.wrap(result) : result + result.respond_to?(:__sync) ? wrap(result) : result end field.redefine { resolve(new_resolve_proc) } diff --git a/spec/fixtures/graphql_schema.rb b/spec/fixtures/graphql_schema.rb index 2a8599b..6e6d148 100644 --- a/spec/fixtures/graphql_schema.rb +++ b/spec/fixtures/graphql_schema.rb @@ -64,4 +64,13 @@ class GraphqlSchema < GraphQL::Schema query QueryType use BatchLoader::GraphQL end + + if defined?(GraphQL::Execution::Interpreter) + class GraphqlSchemaWithInterpreter < GraphQL::Schema + use GraphQL::Execution::Interpreter + use GraphQL::Analysis::AST + query QueryType + use BatchLoader::GraphQL + end + end end diff --git a/spec/graphql_spec.rb b/spec/graphql_spec.rb index 686b4da..496dfa0 100644 --- a/spec/graphql_spec.rb +++ b/spec/graphql_spec.rb @@ -1,7 +1,22 @@ require "spec_helper" RSpec.describe 'GraphQL integration' do + after do + User.destroy_all + Post.destroy_all + end + it 'resolves BatchLoader fields lazily' do + test(GraphqlSchema) + end + + if defined?(GraphqlSchemaWithInterpreter) + it 'resolves BatchLoader fields lazily with GraphQL Interpreter' do + test(GraphqlSchemaWithInterpreter) + end + end + + def test(schema) user1 = User.save(id: "1") user2 = User.save(id: "2") Post.save(user_id: user1.id) @@ -17,7 +32,7 @@ expect(User).to receive(:where).with(id: ["1", "2"]).twice.and_call_original - result = GraphqlSchema.execute(query) + result = schema.execute(query) expect(result['data']).to eq({ 'posts' => [ From cd396ff8282a9cb518dc77e7a124320604c887d1 Mon Sep 17 00:00:00 2001 From: exAspArk Date: Wed, 8 Apr 2020 12:58:57 -0400 Subject: [PATCH 2/2] Deprecate BatchLoader.for in GraphQL --- lib/batch_loader/graphql.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/batch_loader/graphql.rb b/lib/batch_loader/graphql.rb index 372542b..75c52e9 100644 --- a/lib/batch_loader/graphql.rb +++ b/lib/batch_loader/graphql.rb @@ -16,7 +16,7 @@ def self.use(schema_definition) def self.trace(event, _data) if event == 'execute_field' result = yield - result.respond_to?(:__sync) ? wrap(result) : result + result.respond_to?(:__sync) ? wrap_with_warning(result) : result else yield end @@ -26,12 +26,18 @@ def self.instrument(type, field) old_resolve_proc = field.resolve_proc new_resolve_proc = ->(object, arguments, context) do result = old_resolve_proc.call(object, arguments, context) - result.respond_to?(:__sync) ? wrap(result) : result + result.respond_to?(:__sync) ? wrap_with_warning(result) : result end field.redefine { resolve(new_resolve_proc) } end + def self.wrap_with_warning(batch_loader) + warn "DEPRECATION WARNING: using BatchLoader.for in GraphQL is deprecated. Use BatchLoader::GraphQL.for instead or return BatchLoader::GraphQL.wrap from your resolver." + wrap(batch_loader) + end + private_class_method :wrap_with_warning + def self.wrap(batch_loader) BatchLoader::GraphQL.new.tap do |graphql| graphql.batch_loader = batch_loader