graphql-persisted_queries 0.5.0 → 0.5.1

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
2
  SHA256:
3
- metadata.gz: 47cee014870d4382ee5d140302c25a5942ac2e0b8ba3886577a9299e8e097e24
4
- data.tar.gz: 1d0406419d6bcce3137863906d72c3d5a670cf56477c166d54b1dc182e016dfa
3
+ metadata.gz: 248a30a043f26aabeb1f2fb61599b7dc7479a2a90cc1890c4fd7125fb61426e4
4
+ data.tar.gz: 6fbb89bf490bcf11c6681cb624d9153bf7c2be2eeb5bdd486407c288056ab494
5
5
  SHA512:
6
- metadata.gz: b5cf4c0e7d3021dff138122c176983edc1ebbf17ffad0327423389d354e19f6fdc1ef541be58adb5aa4d364aa0e21bf17226ede8dee47cb94f283d677dae326a
7
- data.tar.gz: 10763b571169cdddd8c47c31f4a0350ee8a0a5d3aa6729f6a7669799800b3474810edecd5126c4c6f18c5cf5b52de7ac4f686c5ead9d648eb3032f8cddedbe4c
6
+ metadata.gz: aea67f0744376a70950feea5a331cefd279679c0bc2ed5786f2d2c3fe1a13a31ea87348213b41a0a6d94e7daf32c02cc08364869bb2a088fa0ec2a451f4be793
7
+ data.tar.gz: 458ff6a451faac1fff4e1ce51ad42f9b51bc975270e1666d1730549a726f145acd20ce35ed9d630d62d3ea1c9899e8809c8f755af3d3d53e44af3fe6b30a69d2
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.5.1 (2020-03-18)
6
+
7
+ - [PR#33](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/33) Support AST analyzers ([@DmitryTsepelev][])
8
+
5
9
  ## 0.5.0 (2020-03-12)
6
10
 
7
11
  - [PR#29](https://github.com/DmitryTsepelev/graphql-ruby-persisted_queries/pull/29) Instrumentation via graphql-ruby's tracer feature ([@bmorton][])
data/README.md CHANGED
@@ -14,11 +14,9 @@
14
14
  </a>
15
15
  </p>
16
16
 
17
- ## Installation
17
+ ## Getting started
18
18
 
19
- 1. Add the gem to your Gemfile `gem 'graphql-persisted_queries'`
20
-
21
- 2. Install and configure [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries):
19
+ First of all, install and configure [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) on the front–end side:
22
20
 
23
21
  ```js
24
22
  import { createPersistedQueryLink } from "apollo-link-persisted-queries";
@@ -35,15 +33,25 @@ const client = new ApolloClient({
35
33
  });
36
34
  ```
37
35
 
38
- 3. Add plugin to the schema:
36
+ Add the gem to your Gemfile `gem 'graphql-persisted_queries'` and add the plugin to your schema class:
37
+
38
+ ```ruby
39
+ class GraphqlSchema < GraphQL::Schema
40
+ use GraphQL::PersistedQueries
41
+ end
42
+ ```
43
+
44
+ **Heads up!** If you've already switched to interpreter mode and and AST analyzers—make sure AST plugin is added _before_ `GraphQL::PersistedQueries`:
39
45
 
40
46
  ```ruby
41
47
  class GraphqlSchema < GraphQL::Schema
48
+ use GraphQL::Execution::Interpreter
49
+ use GraphQL::Analysis::AST
42
50
  use GraphQL::PersistedQueries
43
51
  end
44
52
  ```
45
53
 
46
- 4. Pass `:extensions` argument to all calls of `GraphqlSchema#execute` (start with `GraphqlController` and `GraphqlChannel`)
54
+ Pass `:extensions` argument to all calls of `GraphqlSchema#execute`, usually it happens in `GraphqlController`, `GraphqlChannel` and tests.
47
55
 
48
56
  ```ruby
49
57
  GraphqlSchema.execute(
@@ -55,16 +63,11 @@ GraphqlSchema.execute(
55
63
  )
56
64
  ```
57
65
 
58
- 5. Run the app! 🔥
66
+ You're all set!
59
67
 
60
- ## Usage with BatchLink
68
+ ## Advanced usage
61
69
 
62
- It's possible to group queries using [batch-link](https://www.apollographql.com/docs/link/links/batch-http/) and send them as a single HTTP request.
63
- In this case you need to use `GraphqlSchema.multiplex(queries)` instead of `#execute`. The gem supports it too, no action required!
64
-
65
- ## Alternative stores
66
-
67
- All the queries are stored in memory by default, but you can easily switch to _redis_ or _memcached_:
70
+ All the queries are stored in memory by default, but you can easily switch to another storage (e.g., _redis_:
68
71
 
69
72
  ```ruby
70
73
  class GraphqlSchema < GraphQL::Schema
@@ -72,145 +75,20 @@ class GraphqlSchema < GraphQL::Schema
72
75
  end
73
76
  ```
74
77
 
75
- ### Redis
76
-
77
- If you have `ENV["REDIS_URL"]` configured – you don't need to pass it explicitly. Also, you can pass `:redis_host`, `:redis_port` and `:redis_db_name`
78
- inside the `:redis_client` hash to build the URL from scratch or pass the configured `Redis` or `ConnectionPool` object:
79
-
80
- ```ruby
81
- class GraphqlSchema < GraphQL::Schema
82
- use GraphQL::PersistedQueries,
83
- store: :redis,
84
- redis_client: { redis_host: "127.0.0.2", redis_port: "2214", redis_db_name: "7" }
85
- # or
86
- use GraphQL::PersistedQueries,
87
- store: :redis,
88
- redis_client: Redis.new(url: "redis://127.0.0.2:2214/7")
89
- # or
90
- use GraphQL::PersistedQueries,
91
- store: :redis,
92
- redis_client: ConnectionPool.new { Redis.new(url: "redis://127.0.0.2:2214/7") }
93
- end
94
- ```
95
-
96
- You can also pass options for expiration and namespace to override the defaults:
97
-
98
- ```ruby
99
- class GraphqlSchema < GraphQL::Schema
100
- use GraphQL::PersistedQueries,
101
- store: :redis,
102
- redis_client: { redis_url: ENV["MY_REDIS_URL"] },
103
- expiration: 172800, # optional, default is 24 hours
104
- namespace: "my-custom-namespace" # optional, default is "graphql-persisted-query"
105
- end
106
- ```
107
-
108
- ### Memcached
109
-
110
- If you have `ENV["MEMCACHE_SERVERS"]` configured - you don't need to pass it explicitly. Also, you can pass `:memcached_host` and `:memcached_port`
111
- inside the `:dalli_client` hash to build the server name from scratch or pass the configured `Dalli::Client` object:
112
-
113
- ```ruby
114
- class GraphqlSchema < GraphQL::Schema
115
- use GraphQL::PersistedQueries,
116
- store: :memcached,
117
- dalli_client: { memcached_host: "127.0.0.2", memcached_port: "11211" }
118
- # or
119
- use GraphQL::PersistedQueries,
120
- store: :memcached,
121
- dalli_client: Dalli::Client.new("127.0.0.2:11211")
122
- # or
123
- use GraphQL::PersistedQueries,
124
- store: :memcached,
125
- dalli_client: { memcached_url: "127.0.0.2:11211" }
126
- end
127
- ```
128
-
129
- You can also pass options for `expiration` and `namespace` to override the defaults.
130
- Any additional argument inside `dalli_client` will be forwarded to `Dalli::Client.new`.
131
- Following example configures Dalli `pool_size` and `compress` options:
78
+ We currently support `memory`, `redis`, `redis_with_local_cache` and `memcached` out of the box. The detailed documentation can be found [here](docs/alternative_stores.md).
132
79
 
133
- ```ruby
134
- class GraphqlSchema < GraphQL::Schema
135
- use GraphQL::PersistedQueries,
136
- store: :memcached,
137
- dalli_client: {
138
- memcached_url: "127.0.0.2:11211",
139
- pool_size: 5,
140
- compress: true
141
- },
142
- expiration: 172800, # optional, default is 24 hours
143
- namespace: "my-custom-namespace" # optional, default is "graphql-persisted-query"
144
- end
145
- ```
146
-
147
- ### Supported stores
148
-
149
- We currently support a few different stores that can be configured out of the box:
150
-
151
- - `:memory`: This is the default in-memory store and is great for getting started, but will require each instance to cache results independently which can result in lots of ["new query path"](https://blog.apollographql.com/improve-graphql-performance-with-automatic-persisted-queries-c31d27b8e6ea) requests.
152
- - `:redis`: This store will allow you to share a Redis cache across all instances of your GraphQL application so that each instance doesn't have to ask the client for the query again if it hasn't seen it yet.
153
- - `:redis_with_local_cache`: This store combines both the `:memory` and `:redis` approaches so that we can reduce the number of network requests we make while mitigating the independent cache issue. This adapter is configured identically to the `:redis` store.
154
- - `:memcached`: This store will allow you to share a Memcached cache across all instances of your GraphQL application. The client is implemented with the Dalli gem.
155
-
156
- ## Alternative hash functions
157
-
158
- [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) uses _SHA256_ by default so this gem uses it as a default too, but if you want to override it – you can use `:hash_generator` option:
159
-
160
- ```ruby
161
- class GraphqlSchema < GraphQL::Schema
162
- use GraphQL::PersistedQueries, hash_generator: :md5
163
- end
164
- ```
165
-
166
- If string or symbol is passed – the gem would try to find the class in the `Digest` namespace. Altenatively, you can pass a lambda, e.g.:
167
-
168
- ```ruby
169
- class GraphqlSchema < GraphQL::Schema
170
- use GraphQL::PersistedQueries, hash_generator: proc { |_value| "super_safe_hash!!!" }
171
- end
172
- ```
173
-
174
- ## Error handling
175
-
176
- You may optionally specify an object that will be called whenever an error occurs while attempting to resolve or save a query. This will give you the opportunity to both handle (e.g. graceful Redis failure) and/or log the error. By default, errors will be raised when a failure occurs within a `StoreAdapter`.
177
-
178
- An error handler can be a proc or an implementation of `GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler`. Here's an example for treating Redis failures as cache misses:
179
-
180
- ```ruby
181
- class GracefulRedisErrorHandler < GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler
182
- def call(error)
183
- case error
184
- when Redis::BaseError
185
- # Treat Redis errors as a cache miss, but you should log the error into
186
- # your instrumentation framework here.
187
- else
188
- raise error
189
- end
190
-
191
- # Return nothing to ensure handled errors are treated as cache misses
192
- return
193
- end
194
- end
195
-
196
- class GraphqlSchema < GraphQL::Schema
197
- use GraphQL::PersistedQueries, error_handler: GracefulRedisErrorHandler.new
198
- end
199
- ```
80
+ When the error occurs, the gem tries to not interrupt the regular flow of the app (e.g., when something is wrong with the storage, it will just answer that persisted query is not found). You can add a [custom](docs/error_handling.md) error handler and try to fix the problem or just log it.
200
81
 
201
- ## GET requests and HTTP cache
82
+ Since our queries are slim now, we can switch back to HTTP GET, you can find a [guide](docs/http_cache.md) here.
202
83
 
203
- Using `GET` requests for persisted queries allows you to enable HTTP caching (e.g., turn on CDN). This is how to turn them on:
204
- 1. Change the way link is initialized on front-end side (`createPersistedQueryLink({ useGETForHashedQueries: true })`);
205
- 2. Register a new route `get "/graphql", to: "graphql#execute"`;
206
- 3. Put the request object to the GraphQL context in the controller `GraphqlSchema.execute(query, variables: variables, context: { request: request })`;
207
- 4. Turn the `verify_http_method` option on (`use GraphQL::PersistedQueries, verify_http_method: true`) to enforce using `POST` requests for performing mutations (otherwise the error `Mutations cannot be performed via HTTP GET` will be returned).
84
+ [batch-link](https://www.apollographql.com/docs/link/links/batch-http/) allows to group queries on the client side into a single HTTP request before sending to the server. In this case you need to use `GraphqlSchema.multiplex(queries)` instead of `#execute`. The gem supports it too, no action required!
208
85
 
209
- HTTP method verification is important, because when mutations are allowed via `GET` requests, it's easy to perform an attack by sending the link containing mutation to a signed in user.
86
+ [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) uses _SHA256_ for building hashes by default. Check out this [guide](docs/hash.md) if you want to override this behavior.
210
87
 
211
- ## Tracing and instrumentation
88
+ An experimental tracing feature can be enabled by setting `tracing: true` when configuring the plugin. Read more about this feature in the [Tracing guide](docs/tracing.md).
212
89
 
213
- An experimental tracing feature can be enabled by setting `tracing: true` when configuring the plugin. Read more about this feature in the [Tracing guide](docs/tracing.md).
90
+ > 📖 Read more about the gem internals: [Persisted queries in GraphQL:
91
+ Slim down Apollo requests to your Ruby application](https://evilmartians.com/chronicles/persisted-queries-in-graphql-slim-down-apollo-requests-to-your-ruby-application)
214
92
 
215
93
  ## Contributing
216
94
 
@@ -0,0 +1,80 @@
1
+ # Alternative stores
2
+
3
+ We currently support a few different stores that can be configured out of the box:
4
+
5
+ - `:memory`: This is the default in-memory store and is great for getting started, but will require each instance to cache results independently which can result in lots of ["new query path"](https://blog.apollographql.com/improve-graphql-performance-with-automatic-persisted-queries-c31d27b8e6ea) requests.
6
+ - `:redis`: This store will allow you to share a Redis cache across all instances of your GraphQL application so that each instance doesn't have to ask the client for the query again if it hasn't seen it yet.
7
+ - `:redis_with_local_cache`: This store combines both the `:memory` and `:redis` approaches so that we can reduce the number of network requests we make while mitigating the independent cache issue. This adapter is configured identically to the `:redis` store.
8
+ - `:memcached`: This store will allow you to share a Memcached cache across all instances of your GraphQL application. The client is implemented with the Dalli gem.
9
+
10
+ ## Redis
11
+
12
+ If you have `ENV["REDIS_URL"]` configured – you don't need to pass it explicitly. Also, you can pass `:redis_host`, `:redis_port` and `:redis_db_name`
13
+ inside the `:redis_client` hash to build the URL from scratch or pass the configured `Redis` or `ConnectionPool` object:
14
+
15
+ ```ruby
16
+ class GraphqlSchema < GraphQL::Schema
17
+ use GraphQL::PersistedQueries,
18
+ store: :redis,
19
+ redis_client: { redis_host: "127.0.0.2", redis_port: "2214", redis_db_name: "7" }
20
+ # or
21
+ use GraphQL::PersistedQueries,
22
+ store: :redis,
23
+ redis_client: Redis.new(url: "redis://127.0.0.2:2214/7")
24
+ # or
25
+ use GraphQL::PersistedQueries,
26
+ store: :redis,
27
+ redis_client: ConnectionPool.new { Redis.new(url: "redis://127.0.0.2:2214/7") }
28
+ end
29
+ ```
30
+
31
+ You can also pass options for expiration and namespace to override the defaults:
32
+
33
+ ```ruby
34
+ class GraphqlSchema < GraphQL::Schema
35
+ use GraphQL::PersistedQueries,
36
+ store: :redis,
37
+ redis_client: { redis_url: ENV["MY_REDIS_URL"] },
38
+ expiration: 172800, # optional, default is 24 hours
39
+ namespace: "my-custom-namespace" # optional, default is "graphql-persisted-query"
40
+ end
41
+ ```
42
+
43
+ ## Memcached
44
+
45
+ If you have `ENV["MEMCACHE_SERVERS"]` configured - you don't need to pass it explicitly. Also, you can pass `:memcached_host` and `:memcached_port`
46
+ inside the `:dalli_client` hash to build the server name from scratch or pass the configured `Dalli::Client` object:
47
+
48
+ ```ruby
49
+ class GraphqlSchema < GraphQL::Schema
50
+ use GraphQL::PersistedQueries,
51
+ store: :memcached,
52
+ dalli_client: { memcached_host: "127.0.0.2", memcached_port: "11211" }
53
+ # or
54
+ use GraphQL::PersistedQueries,
55
+ store: :memcached,
56
+ dalli_client: Dalli::Client.new("127.0.0.2:11211")
57
+ # or
58
+ use GraphQL::PersistedQueries,
59
+ store: :memcached,
60
+ dalli_client: { memcached_url: "127.0.0.2:11211" }
61
+ end
62
+ ```
63
+
64
+ You can also pass options for `expiration` and `namespace` to override the defaults.
65
+ Any additional argument inside `dalli_client` will be forwarded to `Dalli::Client.new`.
66
+ Following example configures Dalli `pool_size` and `compress` options:
67
+
68
+ ```ruby
69
+ class GraphqlSchema < GraphQL::Schema
70
+ use GraphQL::PersistedQueries,
71
+ store: :memcached,
72
+ dalli_client: {
73
+ memcached_url: "127.0.0.2:11211",
74
+ pool_size: 5,
75
+ compress: true
76
+ },
77
+ expiration: 172800, # optional, default is 24 hours
78
+ namespace: "my-custom-namespace" # optional, default is "graphql-persisted-query"
79
+ end
80
+ ```
@@ -0,0 +1,26 @@
1
+ # Error handling
2
+
3
+ You may optionally specify an object that will be called whenever an error occurs while attempting to resolve or save a query. This will give you the opportunity to both handle (e.g. graceful Redis failure) and/or log the error. By default, errors will be raised when a failure occurs within a `StoreAdapter`.
4
+
5
+ An error handler can be a proc or an implementation of `GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler`. Here's an example for treating Redis failures as cache misses:
6
+
7
+ ```ruby
8
+ class GracefulRedisErrorHandler < GraphQL::PersistedQueries::ErrorHandlers::BaseErrorHandler
9
+ def call(error)
10
+ case error
11
+ when Redis::BaseError
12
+ # Treat Redis errors as a cache miss, but you should log the error into
13
+ # your instrumentation framework here.
14
+ else
15
+ raise error
16
+ end
17
+
18
+ # Return nothing to ensure handled errors are treated as cache misses
19
+ return
20
+ end
21
+ end
22
+
23
+ class GraphqlSchema < GraphQL::Schema
24
+ use GraphQL::PersistedQueries, error_handler: GracefulRedisErrorHandler.new
25
+ end
26
+ ```
data/docs/hash.md ADDED
@@ -0,0 +1,17 @@
1
+ # Alternative hash functions
2
+
3
+ [apollo-link-persisted-queries](https://github.com/apollographql/apollo-link-persisted-queries) uses _SHA256_ by default so this gem uses it as a default too, but if you want to override it – you can use `:hash_generator` option:
4
+
5
+ ```ruby
6
+ class GraphqlSchema < GraphQL::Schema
7
+ use GraphQL::PersistedQueries, hash_generator: :md5
8
+ end
9
+ ```
10
+
11
+ If string or symbol is passed – the gem would try to find the class in the `Digest` namespace. Altenatively, you can pass a lambda, e.g.:
12
+
13
+ ```ruby
14
+ class GraphqlSchema < GraphQL::Schema
15
+ use GraphQL::PersistedQueries, hash_generator: proc { |_value| "super_safe_hash!!!" }
16
+ end
17
+ ```
@@ -0,0 +1,42 @@
1
+ # GET requests and HTTP cache
2
+
3
+ Using `GET` requests for persisted queries allows you to enable HTTP caching (e.g., turn on CDN).
4
+
5
+ Firstly, turn on the `useGETForHashedQueries` parameter on the front-end side:
6
+
7
+ ```js
8
+ import { createPersistedQueryLink } from "apollo-link-persisted-queries";
9
+ import { createHttpLink } from "apollo-link-http";
10
+ import { InMemoryCache } from "apollo-cache-inmemory";
11
+ import ApolloClient from "apollo-client";
12
+
13
+
14
+ // use this with Apollo Client
15
+ const link = createPersistedQueryLink({ useGETForHashedQueries: true }).concat(createHttpLink({ uri: "/graphql" }));
16
+ const client = new ApolloClient({
17
+ cache: new InMemoryCache(),
18
+ link: link,
19
+ });
20
+ ```
21
+
22
+ Register a new route in `routes.rb`:
23
+
24
+ ```ruby
25
+ get "/graphql", to: "graphql#execute"
26
+ ```
27
+
28
+ Put the request object to the GraphQL context everywhere you execute GraphQL queries:
29
+
30
+ ```ruby
31
+ GraphqlSchema.execute(query, variables: variables, context: { request: request })
32
+ ```
33
+
34
+ Turn the `verify_http_method` option when configuring the plugin to enforce using `POST` requests for performing mutations (otherwise the error `Mutations cannot be performed via HTTP GET` will be returned):
35
+
36
+ ```ruby
37
+ class GraphqlSchema < GraphQL::Schema
38
+ use GraphQL::PersistedQueries, verify_http_method: true
39
+ end
40
+ ```
41
+
42
+ HTTP method verification is important, because when mutations are allowed via `GET` requests, it's easy to perform an attack by sending the link containing mutation to a signed in user.
@@ -5,7 +5,6 @@ require "graphql/persisted_queries/schema_patch"
5
5
  require "graphql/persisted_queries/store_adapters"
6
6
  require "graphql/persisted_queries/version"
7
7
  require "graphql/persisted_queries/builder_helpers"
8
- require "graphql/persisted_queries/http_method_analyzer"
9
8
 
10
9
  module GraphQL
11
10
  # Plugin definition
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module Analyzers
6
+ # Verifies that mutations are not executed using GET requests
7
+ class HttpMethodAnalyzer
8
+ def initial_value(query)
9
+ { query: query }
10
+ end
11
+
12
+ def call(memo, _visit_type, _irep_node)
13
+ memo
14
+ end
15
+
16
+ def final_value(memo)
17
+ HttpMethodValidator.new(memo[:query]).perform
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module Analyzers
6
+ # Verifies that mutations are not executed using GET requests
7
+ class HttpMethodAstAnalyzer < GraphQL::Analysis::AST::Analyzer
8
+ def initialize(query)
9
+ super
10
+ @query = query
11
+ end
12
+
13
+ def result
14
+ HttpMethodValidator.new(@query).perform
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module PersistedQueries
5
+ module Analyzers
6
+ # Verifies that mutations are not executed using GET requests
7
+ class HttpMethodValidator
8
+ def initialize(query)
9
+ @query = query
10
+ end
11
+
12
+ def perform
13
+ return if !@query.context[:request]&.get? || !@query.mutation?
14
+
15
+ GraphQL::AnalysisError.new("Mutations cannot be performed via HTTP GET")
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -3,6 +3,7 @@
3
3
  require "graphql/persisted_queries/hash_generator_builder"
4
4
  require "graphql/persisted_queries/resolver"
5
5
  require "graphql/persisted_queries/multiplex_resolver"
6
+ require "graphql/persisted_queries/analyzers/http_method_validator"
6
7
 
7
8
  module GraphQL
8
9
  module PersistedQueries
@@ -35,12 +36,10 @@ module GraphQL
35
36
  def verify_http_method=(verify)
36
37
  return unless verify
37
38
 
38
- analyzer = HttpMethodAnalyzer.new
39
-
40
- if Gem::Dependency.new("graphql", ">= 1.10.0").match?("graphql", GraphQL::VERSION)
41
- query_analyzer(analyzer)
39
+ if graphql10?
40
+ query_analyzer(prepare_analyzer)
42
41
  else
43
- query_analyzers << analyzer
42
+ query_analyzers << prepare_analyzer
44
43
  end
45
44
  end
46
45
 
@@ -60,6 +59,22 @@ module GraphQL
60
59
  persisted_query_store.tracers = tracers if persisted_queries_tracing_enabled?
61
60
  end
62
61
  end
62
+
63
+ private
64
+
65
+ def graphql10?
66
+ Gem::Dependency.new("graphql", ">= 1.10.0").match?("graphql", GraphQL::VERSION)
67
+ end
68
+
69
+ def prepare_analyzer
70
+ if graphql10? && using_ast_analysis?
71
+ require "graphql/persisted_queries/analyzers/http_method_ast_analyzer"
72
+ Analyzers::HttpMethodAstAnalyzer
73
+ else
74
+ require "graphql/persisted_queries/analyzers/http_method_analyzer"
75
+ Analyzers::HttpMethodAnalyzer.new
76
+ end
77
+ end
63
78
  end
64
79
  end
65
80
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module PersistedQueries
5
- VERSION = "0.5.0"
5
+ VERSION = "0.5.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-persisted_queries
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-12 00:00:00.000000000 Z
11
+ date: 2020-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -125,6 +125,10 @@ files:
125
125
  - Rakefile
126
126
  - bin/console
127
127
  - bin/setup
128
+ - docs/alternative_stores.md
129
+ - docs/error_handling.md
130
+ - docs/hash.md
131
+ - docs/http_cache.md
128
132
  - docs/tracing.md
129
133
  - gemfiles/graphql_1_10.gemfile
130
134
  - gemfiles/graphql_1_8.gemfile
@@ -132,12 +136,14 @@ files:
132
136
  - gemfiles/graphql_master.gemfile
133
137
  - graphql-persisted_queries.gemspec
134
138
  - lib/graphql/persisted_queries.rb
139
+ - lib/graphql/persisted_queries/analyzers/http_method_analyzer.rb
140
+ - lib/graphql/persisted_queries/analyzers/http_method_ast_analyzer.rb
141
+ - lib/graphql/persisted_queries/analyzers/http_method_validator.rb
135
142
  - lib/graphql/persisted_queries/builder_helpers.rb
136
143
  - lib/graphql/persisted_queries/error_handlers.rb
137
144
  - lib/graphql/persisted_queries/error_handlers/base_error_handler.rb
138
145
  - lib/graphql/persisted_queries/error_handlers/default_error_handler.rb
139
146
  - lib/graphql/persisted_queries/hash_generator_builder.rb
140
- - lib/graphql/persisted_queries/http_method_analyzer.rb
141
147
  - lib/graphql/persisted_queries/multiplex_resolver.rb
142
148
  - lib/graphql/persisted_queries/resolver.rb
143
149
  - lib/graphql/persisted_queries/schema_patch.rb
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module PersistedQueries
5
- # Verifies that mutations are not executed using GET requests
6
- class HttpMethodAnalyzer
7
- def analyze?(query)
8
- query.context[:request]
9
- end
10
-
11
- def initial_value(query)
12
- {
13
- get_request: query.context[:request]&.get?,
14
- mutation: query.mutation?
15
- }
16
- end
17
-
18
- def call(memo, _visit_type, _irep_node)
19
- memo
20
- end
21
-
22
- def final_value(memo)
23
- return if !memo[:get_request] || !memo[:mutation]
24
-
25
- GraphQL::AnalysisError.new("Mutations cannot be performed via HTTP GET")
26
- end
27
- end
28
- end
29
- end