graphql-batch 0.3.10 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c793255ae48cf638179b9e786d03493a469d1629
4
- data.tar.gz: d235b788e4f9208747d7145e7d2599c2279319d1
2
+ SHA256:
3
+ metadata.gz: c1f52d43c7f189fab24b5e00f8b34435e99c03ae23ba4c99dfaa7a94d67271ed
4
+ data.tar.gz: 0ceb7b68519b2e1bd0f94686376d26590cebb9697fd50e80272d0770a85c4784
5
5
  SHA512:
6
- metadata.gz: 7b263790b1871d54d9258e7bd2541c17361b8177a79e07aac146f9d3ccf05570cf07f8aaac40cf4dbe76c3b6f1677f3cd957a32904742c069a133d3906044767
7
- data.tar.gz: d00d449a8872286251cc21d555b54be0690002f697dddb8afc1f43e6b90d75e42367ad70f54c701fc75d89b04427b4d127879481c406a24555d3ada35ce0582f
6
+ metadata.gz: '091fe19e752f10751216374384346e2c4bb0d8fbe35e86248b3584396531ff2775b4732380da5109968b402320ca22e0cc2f1f772ca26f9d12b4b2bfc5a5a049'
7
+ data.tar.gz: 6890562c5b66004bf10b886ba6370cf7c544ab796f2e29ac279b49c93003079b1722c068155a168f5ee9f3194b34395a2d26ac2e8e3013cecd6e74db2286d8ad
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1
4
- - 2.2
5
3
  - 2.3
6
- - 2.4
7
- before_install: gem install bundler -v 1.13.3
4
+ - 2.6
5
+ env:
6
+ - TESTING_INTERPRETER=true
7
+ - TESTING_INTERPRETER=false
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ if ENV["TESTING_INTERPRETER"] == "true"
6
+ gem "graphql", "1.9.0.pre4"
7
+ end
data/README.md CHANGED
@@ -25,6 +25,8 @@ Or install it yourself as:
25
25
 
26
26
  ### Basic Usage
27
27
 
28
+ #### Schema Configuration
29
+
28
30
  Require the library
29
31
 
30
32
  ```ruby
@@ -49,8 +51,9 @@ end
49
51
  Use `GraphQL::Batch` as a plugin in your schema (for graphql >= `1.5.0`).
50
52
 
51
53
  ```ruby
52
- MySchema = GraphQL::Schema.define do
54
+ class MySchema < GraphQL::Schema
53
55
  query MyQueryType
56
+ mutation MyMutationType
54
57
 
55
58
  use GraphQL::Batch
56
59
  end
@@ -66,16 +69,39 @@ MySchema = GraphQL::Schema.define do
66
69
  end
67
70
  ```
68
71
 
69
- The loader class can be used from the resolve proc for a graphql field by calling `.for` with the grouping arguments to get a loader instance, then call `.load` on that instance with the key to load.
72
+ ##### With `1.9.0`'s `Interpreter` runtime
73
+
74
+ Add `GraphQL::Batch` _after_ the interpreter, so that `GraphQL::Batch` can detect the interpreter and attach the right integrations:
75
+
76
+ ```ruby
77
+ use GraphQL::Execution::Interpreter
78
+ use GraphQL::Batch
79
+ ```
80
+
81
+ #### Field Usage
82
+
83
+ The loader class can be used from the resolver for a graphql field by calling `.for` with the grouping arguments to get a loader instance, then call `.load` on that instance with the key to load.
70
84
 
71
85
  ```ruby
72
- resolve -> (obj, args, context) { RecordLoader.for(Product).load(args["id"]) }
86
+ field :product, Types::Product, null: true do
87
+ argument :id, ID, required: true
88
+ end
89
+
90
+ def product(id:)
91
+ RecordLoader.for(Product).load(id)
92
+ end
73
93
  ```
74
94
 
75
95
  The loader also supports batch loading an array of records instead of just a single record, via `load_many`. For example:
76
96
 
77
97
  ```ruby
78
- resolve -> (obj, args, context) { RecordLoader.for(Product).load_many(args["ids"]) }
98
+ field :products, [Types::Product, null: true], null: false do
99
+ argument :ids, [ID], required: true
100
+ end
101
+
102
+ def product(ids:)
103
+ RecordLoader.for(Product).load_many(ids)
104
+ end
79
105
  ```
80
106
 
81
107
  Although this library doesn't have a dependency on active record,
@@ -89,8 +115,8 @@ on records with the same id.
89
115
  GraphQL::Batch::Loader#load returns a Promise using the [promise.rb gem](https://rubygems.org/gems/promise.rb) to provide a promise based API, so you can transform the query results using `.then`
90
116
 
91
117
  ```ruby
92
- resolve -> (obj, args, context) do
93
- RecordLoader.for(Product).load(args["id"]).then do |product|
118
+ def product_title(id:)
119
+ RecordLoader.for(Product).load(id).then do |product|
94
120
  product.title
95
121
  end
96
122
  end
@@ -99,8 +125,8 @@ end
99
125
  You may also need to do another query that depends on the first one to get the result, in which case the query block can return another query.
100
126
 
101
127
  ```ruby
102
- resolve -> (obj, args, context) do
103
- RecordLoader.for(Product).load(args["id"]).then do |product|
128
+ def product_image(id:)
129
+ RecordLoader.for(Product).load(id).then do |product|
104
130
  RecordLoader.for(Image).load(product.image_id)
105
131
  end
106
132
  end
@@ -109,7 +135,7 @@ end
109
135
  If the second query doesn't depend on the first one, then you can use Promise.all, which allows each query in the group to be batched with other queries.
110
136
 
111
137
  ```ruby
112
- resolve -> (obj, args, context) do
138
+ def all_collections
113
139
  Promise.all([
114
140
  CountLoader.for(Shop, :smart_collections).load(context.shop_id),
115
141
  CountLoader.for(Shop, :custom_collections).load(context.shop_id),
@@ -122,8 +148,10 @@ end
122
148
  `.then` can optionally take two lambda arguments, the first of which is equivalent to passing a block to `.then`, and the second one handles exceptions. This can be used to provide a fallback
123
149
 
124
150
  ```ruby
125
- resolve -> (obj, args, context) do
151
+ def product(id:)
152
+ # Try the cache first ...
126
153
  CacheLoader.for(Product).load(args["id"]).then(nil, lambda do |exc|
154
+ # But if there's a connection error, go to the underlying database
127
155
  raise exc unless exc.is_a?(Redis::BaseConnectionError)
128
156
  logger.warn err.message
129
157
  RecordLoader.for(Product).load(args["id"])
@@ -18,13 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_runtime_dependency "graphql", ">= 0.8", "< 2"
21
+ spec.add_runtime_dependency "graphql", ">= 1.3", "< 2"
22
22
  spec.add_runtime_dependency "promise.rb", "~> 0.7.2"
23
23
 
24
- if RUBY_ENGINE == 'ruby' && Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.2")
25
- spec.add_development_dependency "byebug"
26
- end
27
- spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "byebug" if RUBY_ENGINE == 'ruby'
28
25
  spec.add_development_dependency "rake", "~> 10.0"
29
26
  spec.add_development_dependency "minitest"
30
27
  end
@@ -1,7 +1,4 @@
1
1
  require "graphql"
2
- if Gem::Version.new(GraphQL::VERSION) < Gem::Version.new("1.3")
3
- warn "graphql gem versions less than 1.3 are deprecated for use with graphql-batch, upgrade so lazy_resolve can be used"
4
- end
5
2
  require "promise.rb"
6
3
 
7
4
  module GraphQL
@@ -20,7 +17,17 @@ module GraphQL
20
17
 
21
18
  def self.use(schema_defn, executor_class: GraphQL::Batch::Executor)
22
19
  schema = schema_defn.target
23
- if GraphQL::VERSION >= "1.6.0"
20
+ if Gem::Version.new(GraphQL::VERSION) >= Gem::Version.new('1.9.0.pre3')
21
+ require_relative "batch/mutation_field_extension"
22
+ if schema.mutation
23
+ schema.mutation.fields.each do |name, f|
24
+ field = f.metadata[:type_class]
25
+ field.extension(GraphQL::Batch::MutationFieldExtension)
26
+ end
27
+ end
28
+ instrumentation = GraphQL::Batch::SetupMultiplex.new(schema, executor_class: executor_class)
29
+ schema_defn.instrument(:multiplex, instrumentation)
30
+ elsif GraphQL::VERSION >= "1.6.0"
24
31
  instrumentation = GraphQL::Batch::SetupMultiplex.new(schema, executor_class: executor_class)
25
32
  schema_defn.instrument(:multiplex, instrumentation)
26
33
  schema_defn.instrument(:field, instrumentation)
@@ -31,15 +38,11 @@ module GraphQL
31
38
  end
32
39
  schema_defn.lazy_resolve(::Promise, :sync)
33
40
  end
34
-
35
- autoload :ExecutionStrategy, 'graphql/batch/execution_strategy'
36
- autoload :MutationExecutionStrategy, 'graphql/batch/mutation_execution_strategy'
37
41
  end
38
42
  end
39
43
 
40
44
  require_relative "batch/version"
41
45
  require_relative "batch/loader"
42
46
  require_relative "batch/executor"
43
- require_relative "batch/promise"
44
47
  require_relative "batch/setup"
45
48
  require_relative "batch/setup_multiplex"
@@ -1,8 +1,5 @@
1
1
  module GraphQL::Batch
2
2
  class Loader
3
- NoExecutorError = GraphQL::Batch::NoExecutorError
4
- deprecate_constant :NoExecutorError if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3")
5
-
6
3
  def self.for(*group_args)
7
4
  loader_key = loader_key_for(*group_args)
8
5
  executor = Executor.current
@@ -0,0 +1,12 @@
1
+ module GraphQL::Batch
2
+ class MutationFieldExtension < GraphQL::Schema::FieldExtension
3
+ def resolve(object:, arguments:, **_rest)
4
+ GraphQL::Batch::Executor.current.clear
5
+ begin
6
+ ::Promise.sync(yield(object, arguments))
7
+ ensure
8
+ GraphQL::Batch::Executor.current.clear
9
+ end
10
+ end
11
+ end
12
+ end
@@ -23,15 +23,6 @@ module GraphQL::Batch
23
23
  }
24
24
  end
25
25
  end
26
-
27
- def before_query(query)
28
- warn "Deprecated graphql-batch setup `instrument(:query, GraphQL::Batch::Setup)`, replace with `use GraphQL::Batch`"
29
- start_batching(GraphQL::Batch::Executor)
30
- end
31
-
32
- def after_query(query)
33
- end_batching
34
- end
35
26
  end
36
27
 
37
28
  def initialize(schema, executor_class:)
@@ -1,5 +1,5 @@
1
1
  module GraphQL
2
2
  module Batch
3
- VERSION = "0.3.10"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-batch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.10
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Thacker-Smith
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-22 00:00:00.000000000 Z
11
+ date: 2019-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.8'
19
+ version: '1.3'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '2'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '0.8'
29
+ version: '1.3'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2'
@@ -58,20 +58,6 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
- - !ruby/object:Gem::Dependency
62
- name: bundler
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '1.10'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '1.10'
75
61
  - !ruby/object:Gem::Dependency
76
62
  name: rake
77
63
  requirement: !ruby/object:Gem::Requirement
@@ -120,11 +106,9 @@ files:
120
106
  - examples/record_loader.rb
121
107
  - graphql-batch.gemspec
122
108
  - lib/graphql/batch.rb
123
- - lib/graphql/batch/execution_strategy.rb
124
109
  - lib/graphql/batch/executor.rb
125
110
  - lib/graphql/batch/loader.rb
126
- - lib/graphql/batch/mutation_execution_strategy.rb
127
- - lib/graphql/batch/promise.rb
111
+ - lib/graphql/batch/mutation_field_extension.rb
128
112
  - lib/graphql/batch/setup.rb
129
113
  - lib/graphql/batch/setup_multiplex.rb
130
114
  - lib/graphql/batch/version.rb
@@ -148,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
132
  version: '0'
149
133
  requirements: []
150
134
  rubyforge_project:
151
- rubygems_version: 2.6.14
135
+ rubygems_version: 2.7.6
152
136
  signing_key:
153
137
  specification_version: 4
154
138
  summary: A query batching executor for the graphql gem
@@ -1,67 +0,0 @@
1
- warn "GraphQL::Batch::ExecutionStrategy is deprecated, instead add `use GraphQL::Batch` in GraphQL::Schema.define"
2
-
3
- module GraphQL::Batch
4
- class ExecutionStrategy < GraphQL::Query::SerialExecution
5
- def execute(_, _, query)
6
- GraphQL::Batch.batch do
7
- as_promise_unless_resolved(super)
8
- end
9
- rescue GraphQL::InvalidNullError => err
10
- err.parent_error? || query.context.errors.push(err)
11
- nil
12
- end
13
-
14
- # Needed for MutationExecutionStrategy
15
- def deep_sync(result) #:nodoc:
16
- ::Promise.sync(as_promise_unless_resolved(result))
17
- end
18
-
19
- private
20
-
21
- def as_promise_unless_resolved(result)
22
- all_promises = []
23
- each_promise(result) do |obj, key, promise|
24
- obj[key] = nil
25
- all_promises << promise.then do |value|
26
- obj[key] = value
27
- as_promise_unless_resolved(value)
28
- end
29
- end
30
- return result if all_promises.empty?
31
- ::Promise.all(all_promises).then { result }
32
- end
33
-
34
- def each_promise(obj, &block)
35
- case obj
36
- when Array
37
- obj.each_with_index do |value, idx|
38
- each_promise_in_entry(obj, idx, value, &block)
39
- end
40
- when Hash
41
- obj.each do |key, value|
42
- each_promise_in_entry(obj, key, value, &block)
43
- end
44
- end
45
- end
46
-
47
- def each_promise_in_entry(obj, key, value, &block)
48
- if value.is_a?(::Promise)
49
- yield obj, key, value
50
- else
51
- each_promise(value, &block)
52
- end
53
- end
54
-
55
- class FieldResolution < GraphQL::Query::SerialExecution::FieldResolution
56
- def get_finished_value(raw_value)
57
- if raw_value.is_a?(::Promise)
58
- raw_value.then(->(result) { super(result) }, lambda do |error|
59
- error.is_a?(GraphQL::ExecutionError) ? super(error) : raise(error)
60
- end)
61
- else
62
- super
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,23 +0,0 @@
1
- require_relative "execution_strategy"
2
-
3
- module GraphQL::Batch
4
- class MutationExecutionStrategy < GraphQL::Batch::ExecutionStrategy
5
- attr_accessor :enable_batching
6
-
7
- class FieldResolution < GraphQL::Batch::ExecutionStrategy::FieldResolution
8
- def get_finished_value(raw_value)
9
- strategy = execution_context.strategy
10
- return super if strategy.enable_batching
11
-
12
- GraphQL::Batch::Executor.current.clear
13
- begin
14
- strategy.enable_batching = true
15
- strategy.deep_sync(::Promise.sync(super))
16
- ensure
17
- strategy.enable_batching = false
18
- GraphQL::Batch::Executor.current.clear
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,6 +0,0 @@
1
- module GraphQL::Batch
2
- Promise = ::Promise
3
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3")
4
- deprecate_constant :Promise
5
- end
6
- end