graphql_connector 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +3 -2
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +4 -4
- data/README.md +117 -5
- data/examples/departments_service_class_examples.rb +38 -0
- data/examples/query_examples.rb +16 -0
- data/examples/raw_query_examples.rb +19 -0
- data/graphql_connector.gemspec +6 -5
- data/lib/graphql_connector.rb +5 -1
- data/lib/graphql_connector/base_server_type.rb +17 -2
- data/lib/graphql_connector/configuration.rb +1 -0
- data/lib/graphql_connector/http_client.rb +4 -3
- data/lib/graphql_connector/service_classable/class_method_validator.rb +31 -0
- data/lib/graphql_connector/service_classable/params_validator.rb +24 -0
- data/lib/graphql_connector/service_classable/queryable.rb +76 -0
- data/lib/graphql_connector/service_classable/return_fields_validator.rb +43 -0
- data/lib/graphql_connector/version.rb +1 -1
- metadata +14 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf451963eb895b192df3959d06d56ea22588c2a38c284743f8289ecbebdc4e7e
|
4
|
+
data.tar.gz: 73b57eb9b9569feb90497f96eb286192cd96d08370a181f92ab15a8855b56294
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e41d9ba90e6c33af01647e08243600e19d8c0d412c7701f3d8e0d4c4d0cecd3e3b5b7312c881b8db3782ab28c911b2e5d7541f8bf655fef21e6b980923a65c55
|
7
|
+
data.tar.gz: 9f496a3930e93affe9401a2e7ea0217471d2438619126ba243854202696fba634ed5b592b2a6a87c78daeb592bc4e1a509d9948a7c6012e72b9105a1265c5d3b
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 1.1.0 (2020-4-19)
|
2
|
+
|
3
|
+
### Features
|
4
|
+
* Allow building graphql querying in custom classes via `service class inclusion`
|
5
|
+
* See `README` for details about `service class inclusion`
|
6
|
+
|
7
|
+
### BugFix
|
8
|
+
* Forward `variables` when performing a `raw_query`
|
9
|
+
|
1
10
|
## 1.0.0 (2020-1-26)
|
2
11
|
|
3
12
|
### Breaking
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
graphql_connector (1.
|
4
|
+
graphql_connector (1.1.0)
|
5
5
|
httparty (~> 0.17)
|
6
6
|
|
7
7
|
GEM
|
@@ -10,12 +10,12 @@ GEM
|
|
10
10
|
ast (2.4.0)
|
11
11
|
coderay (1.1.2)
|
12
12
|
diff-lcs (1.3)
|
13
|
-
httparty (0.17.
|
13
|
+
httparty (0.17.3)
|
14
14
|
mime-types (~> 3.0)
|
15
15
|
multi_xml (>= 0.5.2)
|
16
16
|
jaro_winkler (1.5.3)
|
17
17
|
method_source (0.9.2)
|
18
|
-
mime-types (3.3)
|
18
|
+
mime-types (3.3.1)
|
19
19
|
mime-types-data (~> 3.2015)
|
20
20
|
mime-types-data (3.2019.1009)
|
21
21
|
multi_xml (0.6.0)
|
@@ -62,4 +62,4 @@ DEPENDENCIES
|
|
62
62
|
rubocop (~> 0.75)
|
63
63
|
|
64
64
|
BUNDLED WITH
|
65
|
-
2.
|
65
|
+
2.1.2
|
data/README.md
CHANGED
@@ -33,19 +33,31 @@ You need to configure the `graphql_connector` first:
|
|
33
33
|
GraphqlConnector.configure do |config|
|
34
34
|
config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
|
35
35
|
end
|
36
|
+
```
|
36
37
|
|
37
38
|
For each graphql server you wish to query use `add_server`.
|
38
|
-
|
39
|
+
|
40
|
+
Afterwards you will have the following options to fetch and/or mutate data with
|
41
|
+
one or many graphql servers:
|
42
|
+
|
43
|
+
* `raw_query` --> [Examples](examples/raw_query_examples.rb)
|
44
|
+
* `query` --> [Examples](examples/query_examples.rb)
|
45
|
+
* `service class inclusion` --> [Examples](examples/departments_service_class_examples.rb)
|
46
|
+
|
47
|
+
See the following sub sections for details
|
39
48
|
|
40
49
|
### raw_query
|
41
50
|
|
42
|
-
|
51
|
+
You can call your graphql_endpoint via:
|
43
52
|
```ruby
|
44
53
|
GraphqlConnector::<name>.raw_query(query_string)
|
45
54
|
```
|
46
55
|
|
47
|
-
Note that `<name>` has to be replaced by any of the ones added via `
|
56
|
+
Note that `<name>` has to be replaced by any of the ones added via `add_server`
|
57
|
+
|
58
|
+
See also [here](examples/raw_query_examples.rb) for example usage
|
48
59
|
|
60
|
+
---
|
49
61
|
### query
|
50
62
|
|
51
63
|
You can also use the more comfortable `query`:
|
@@ -64,9 +76,11 @@ GraphqlConnector::<name>.query(model, condition, selected_fields)
|
|
64
76
|
> supported with OpenStruct, associated objects are still a normal array of
|
65
77
|
> hashes.
|
66
78
|
|
79
|
+
See also [here](examples/query_examples.rb) for example usage
|
80
|
+
|
67
81
|
#### selected_fields
|
68
82
|
|
69
|
-
The
|
83
|
+
The syntax for the associations looks like the following:
|
70
84
|
```
|
71
85
|
['<attribute_name>', <association_name>: ['<attribute_name_of_the_association>']]
|
72
86
|
```
|
@@ -76,6 +90,104 @@ Example:
|
|
76
90
|
['id', 'name', productCategory: ['id', 'name']]
|
77
91
|
```
|
78
92
|
|
93
|
+
---
|
94
|
+
|
95
|
+
### Service class inclusion
|
96
|
+
|
97
|
+
This approach can be used to `graphqlize` **any** kind of ruby (service) class
|
98
|
+
so that it has re-usable graphql query methods.
|
99
|
+
|
100
|
+
* First add `extend GraphqlConnector::<server>::Query` in the the class(es) that should be `graphqlized`
|
101
|
+
* Next for each mapping add a `add_query` or `add_raw_query` aliasing the graphql server type supports as follows:
|
102
|
+
* `add_query <alias>: <query type in graphql server>, params: [<any kind of query type params>], returns: [<selected_fields>]`
|
103
|
+
* `add_raw_query <alias>: <query string>, params: [<any kind of query type params>]`
|
104
|
+
* If <query type>/<query string> does not need them, omit `params`
|
105
|
+
|
106
|
+
See also [here](examples/departments_service_class_examples.rb) for example usage as also in the following:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
GraphqlConnector.configure do |config|
|
110
|
+
config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
|
111
|
+
end
|
112
|
+
|
113
|
+
# product.rb
|
114
|
+
class Product
|
115
|
+
extend GraphqlConnector::Foo::Query
|
116
|
+
|
117
|
+
add_query all: :products,
|
118
|
+
returns: [:id, :name]
|
119
|
+
|
120
|
+
add_query by_id: :products,
|
121
|
+
params: :id,
|
122
|
+
returns: [:name, product_category: [:id, :name]]
|
123
|
+
|
124
|
+
add_query by_names: :products,
|
125
|
+
params: :names,
|
126
|
+
returns: [:id, :name, product_category: [:id, :name]]
|
127
|
+
|
128
|
+
add_query by: :products,
|
129
|
+
params: [:id, :name],
|
130
|
+
returns: [:name]
|
131
|
+
|
132
|
+
add_query by_category_id: :products,
|
133
|
+
params: :product_category,
|
134
|
+
returns: [product_category: [:id, :name]]
|
135
|
+
end
|
136
|
+
|
137
|
+
Product.all
|
138
|
+
=> [OpenStruct<id=1, name='Demo Product', ...]
|
139
|
+
|
140
|
+
Product.by_id(id: 1)
|
141
|
+
=> [OpenStruct<name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>]
|
142
|
+
|
143
|
+
Product.by_names(names: ['Demo Product', 'Non Demo Product'])
|
144
|
+
=> [OpenStruct<id=1, name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>, Product<id=2, name='Demo Product' ...]
|
145
|
+
|
146
|
+
Product.by(id: 1, name: 'Demo Product')
|
147
|
+
=> OpenStruct<name='Demo Product'>
|
148
|
+
|
149
|
+
Product.by_category_id(product_category: { id: 10})
|
150
|
+
=> OpenStruct<product_category=<ProductCategory<id=10, name='Demo Category'>>
|
151
|
+
```
|
152
|
+
|
153
|
+
Also custom **class methods** can used to call any kind of `query` and do further selection instead:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Product
|
157
|
+
extend GraphqlConnector::Foo::Query
|
158
|
+
|
159
|
+
add_query all: :products, returns: [:name]
|
160
|
+
|
161
|
+
def self.by_id(id:)
|
162
|
+
all.select { |products| products.id == id }.first
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
Product.by_id(id: 1)
|
167
|
+
=> OpenStruct<id=1, name='Demo Product'>>
|
168
|
+
```
|
169
|
+
|
170
|
+
Example for `raw_query`:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
class Product
|
174
|
+
extend GraphqlConnector::Foo::Query
|
175
|
+
|
176
|
+
add_raw_query all: ' query { products { id name } } '
|
177
|
+
add_raw_query by: ' query products($id: !ID, $name: !String) '\
|
178
|
+
'{ products(id: $id, name: $name) { id name } }',
|
179
|
+
params: [:id, :name]
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
Product.all
|
184
|
+
=> [ { id: '1', name: 'Demo Product' }, ...]
|
185
|
+
|
186
|
+
Product.by(id: '1', name: 'Demo Product')
|
187
|
+
=> { id: '1', name: 'Demo Product' }
|
188
|
+
|
189
|
+
```
|
190
|
+
|
79
191
|
## Development
|
80
192
|
|
81
193
|
After checking out the repo, run
|
@@ -100,4 +212,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
100
212
|
|
101
213
|
## Code of Conduct
|
102
214
|
|
103
|
-
Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
215
|
+
Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Garllon/graphql_connector/blob/master/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
|
4
|
+
GraphqlConnector.configure do |config|
|
5
|
+
config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
|
6
|
+
end
|
7
|
+
|
8
|
+
# Service class for fetching department data
|
9
|
+
class Department
|
10
|
+
extend GraphqlConnector::RailsGraphqlServer::Query
|
11
|
+
|
12
|
+
add_query all: :departments, returns: [:id, :name, employees: [:yearlySalary]]
|
13
|
+
|
14
|
+
add_query by_id: :departments,
|
15
|
+
params: [:id],
|
16
|
+
returns: [:id, :name, employees: [:yearlySalary]]
|
17
|
+
|
18
|
+
add_raw_query all_raw: 'query {
|
19
|
+
departments {
|
20
|
+
id name employees { yearlySalary }
|
21
|
+
}
|
22
|
+
}'
|
23
|
+
|
24
|
+
add_raw_query by_id_raw: 'query departments($id: [ID!]) {
|
25
|
+
departments(id: $id) {
|
26
|
+
name employees { name }
|
27
|
+
}
|
28
|
+
}',
|
29
|
+
params: [:id]
|
30
|
+
end
|
31
|
+
|
32
|
+
Department.all
|
33
|
+
|
34
|
+
Department.by_id(id: %w[1 2])
|
35
|
+
|
36
|
+
Department.all_raw
|
37
|
+
|
38
|
+
Department.by_id_raw(id: %w[1 2])
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
|
4
|
+
GraphqlConnector.configure do |config|
|
5
|
+
config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
|
6
|
+
end
|
7
|
+
|
8
|
+
GraphqlConnector::RailsGraphqlServer.query('departments',
|
9
|
+
{},
|
10
|
+
['id', 'name',
|
11
|
+
'employees' => ['yearlySalary']])
|
12
|
+
|
13
|
+
GraphqlConnector::RailsGraphqlServer.query('departments',
|
14
|
+
{ id: %w[1 2] },
|
15
|
+
['id', 'name',
|
16
|
+
'employees' => ['yearlySalary']])
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
GraphqlConnector.configure do |config|
|
4
|
+
config.add_server(name: 'RailsGraphqlServer',
|
5
|
+
uri: 'http://rails-graphql-server.herokuapp.com/api/graphql',
|
6
|
+
headers: {})
|
7
|
+
end
|
8
|
+
|
9
|
+
GraphqlConnector::RailsGraphqlServer.raw_query(
|
10
|
+
'query { departments { id name employees { yearlySalary } } }'
|
11
|
+
)
|
12
|
+
|
13
|
+
GraphqlConnector::RailsGraphqlServer.raw_query(
|
14
|
+
'query departments($id: [ID!]) {
|
15
|
+
departments(id: $id) { name employees { name }
|
16
|
+
}
|
17
|
+
}',
|
18
|
+
variables: { id: %w[1 2] }
|
19
|
+
)
|
data/graphql_connector.gemspec
CHANGED
@@ -7,12 +7,13 @@ require 'graphql_connector/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'graphql_connector'
|
9
9
|
spec.version = GraphqlConnector::VERSION
|
10
|
-
spec.authors = [
|
11
|
-
spec.email = ['palluthe.bennet@gmail.com']
|
10
|
+
spec.authors = %w[Garllon sushie1984]
|
11
|
+
spec.email = ['palluthe.bennet@gmail.com', 'sascha_burku@yahoo.de']
|
12
12
|
|
13
|
-
spec.summary = '
|
14
|
-
spec.description = '
|
15
|
-
'
|
13
|
+
spec.summary = 'GraphQL client'
|
14
|
+
spec.description = 'Grahql client to query with your own raw string, '\
|
15
|
+
'with the small helper method query or with service '\
|
16
|
+
'class inclusion.'
|
16
17
|
spec.homepage = 'https://github.com/Garllon/graphql_connector/blob/master/README.md'
|
17
18
|
spec.license = 'MIT'
|
18
19
|
|
data/lib/graphql_connector.rb
CHANGED
@@ -5,6 +5,10 @@ require 'graphql_connector/query_builder'
|
|
5
5
|
require 'graphql_connector/configuration'
|
6
6
|
require 'graphql_connector/http_client'
|
7
7
|
require 'graphql_connector/base_server_type'
|
8
|
+
require 'graphql_connector/service_classable/class_method_validator'
|
9
|
+
require 'graphql_connector/service_classable/params_validator'
|
10
|
+
require 'graphql_connector/service_classable/return_fields_validator'
|
11
|
+
require 'graphql_connector/service_classable/queryable'
|
8
12
|
require 'graphql_connector/custom_attribute_error'
|
9
13
|
require 'httparty'
|
10
14
|
|
@@ -21,7 +25,7 @@ module GraphqlConnector
|
|
21
25
|
end
|
22
26
|
|
23
27
|
def self.reset
|
24
|
-
@configuration
|
28
|
+
@configuration.reset!
|
25
29
|
end
|
26
30
|
|
27
31
|
def self.configure
|
@@ -11,6 +11,7 @@ module GraphqlConnector
|
|
11
11
|
base_object = GraphqlConnector.const_set(name, base_class)
|
12
12
|
inject_http_client(base_object)
|
13
13
|
inject_query_methods(base_object)
|
14
|
+
create_service_class_module(base_object)
|
14
15
|
|
15
16
|
base_object
|
16
17
|
end
|
@@ -25,6 +26,20 @@ module GraphqlConnector
|
|
25
26
|
'configuration!'
|
26
27
|
end
|
27
28
|
|
29
|
+
def create_service_class_module(base_object)
|
30
|
+
base_object.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
31
|
+
module Query
|
32
|
+
def self.extended(base)
|
33
|
+
base.extend(GraphqlConnector::ServiceClassable::Queryable)
|
34
|
+
end
|
35
|
+
|
36
|
+
def http_client
|
37
|
+
#{base_object}.http_client
|
38
|
+
end
|
39
|
+
end
|
40
|
+
METHOD
|
41
|
+
end
|
42
|
+
|
28
43
|
def class_with(uri, headers)
|
29
44
|
Class.new do
|
30
45
|
attr_accessor :uri, :headers
|
@@ -47,8 +62,8 @@ module GraphqlConnector
|
|
47
62
|
http_client.query(model, conditions, selected_fields)
|
48
63
|
end
|
49
64
|
|
50
|
-
def raw_query(query_string)
|
51
|
-
http_client.raw_query(query_string)
|
65
|
+
def raw_query(query_string, variables: {})
|
66
|
+
http_client.raw_query(query_string, variables: variables)
|
52
67
|
end
|
53
68
|
end
|
54
69
|
end
|
@@ -13,16 +13,17 @@ module GraphqlConnector
|
|
13
13
|
conditions,
|
14
14
|
selected_fields).create
|
15
15
|
parsed_body = raw_query(query_string)
|
16
|
-
result = parsed_body['data'][model]
|
16
|
+
result = parsed_body['data'][model.to_s]
|
17
17
|
return OpenStruct.new(result) unless result.is_a? Array
|
18
18
|
|
19
19
|
result.map { |entry| OpenStruct.new(entry) }
|
20
20
|
end
|
21
21
|
|
22
|
-
def raw_query(query_string)
|
22
|
+
def raw_query(query_string, variables: {})
|
23
23
|
response = HTTParty.post(@uri,
|
24
24
|
headers: @headers,
|
25
|
-
body: { query: query_string
|
25
|
+
body: { query: query_string,
|
26
|
+
variables: variables })
|
26
27
|
parsed_body = JSON.parse(response.body)
|
27
28
|
verify_response!(parsed_body)
|
28
29
|
parsed_body
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlConnector
|
4
|
+
module ServiceClassable
|
5
|
+
class ClassMethodAlreadyImplementedError < StandardError; end
|
6
|
+
class InvalidClassTypeError < StandardError; end
|
7
|
+
# Checks whether a class method for a specific graphql query is in an
|
8
|
+
# expected format
|
9
|
+
class ClassMethodValidator
|
10
|
+
class << self
|
11
|
+
def validate_class_method(class_method_name, invoked_class)
|
12
|
+
return unless invoked_class.singleton_methods
|
13
|
+
.map(&:to_s)
|
14
|
+
.include?(class_method_name.to_s)
|
15
|
+
|
16
|
+
error_msg = "The (raw_)add_query '#{class_method_name}: ... ' is "\
|
17
|
+
'already implemented within the context of '\
|
18
|
+
"#{invoked_class} and therefore cannot be used!"
|
19
|
+
raise ClassMethodAlreadyImplementedError, error_msg
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_element_class_type(element, class_types)
|
23
|
+
return if element.class == class_types
|
24
|
+
|
25
|
+
raise InvalidClassTypeError, "Please ensure that #{element} is a"\
|
26
|
+
"#{class_types}!"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlConnector
|
4
|
+
module ServiceClassable
|
5
|
+
class InvalidParamsError < StandardError; end
|
6
|
+
# Checks whether params for a specifc graphql query are in an expected
|
7
|
+
# format
|
8
|
+
class ParamsValidator
|
9
|
+
class << self
|
10
|
+
def validate(query_params)
|
11
|
+
params = [query_params].flatten
|
12
|
+
return if params.empty? ||
|
13
|
+
params.map(&:class).uniq == [Symbol] ||
|
14
|
+
params.map(&:class).uniq == [String]
|
15
|
+
|
16
|
+
raise InvalidParamsError,
|
17
|
+
"Please ensure that #{query_params} are either "\
|
18
|
+
'Symbols/Strings as described in the README '\
|
19
|
+
'(e.g.: params: [:id, :name])'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlConnector
|
4
|
+
module ServiceClassable
|
5
|
+
# Module that allows to build query methods within the context of
|
6
|
+
# service class
|
7
|
+
module Queryable
|
8
|
+
CONDITIONS = 'binding.local_variables.map do |var|
|
9
|
+
[var, binding.local_variable_get(var)]
|
10
|
+
end.to_h'
|
11
|
+
|
12
|
+
def add_query(params: [], returns:, **method_to_query)
|
13
|
+
class_method_name = method_to_query.first[0]
|
14
|
+
query_type = method_to_query.first[1]
|
15
|
+
ReturnFieldsValidator.validate(returns)
|
16
|
+
ClassMethodValidator.validate_class_method(class_method_name, self)
|
17
|
+
ClassMethodValidator.validate_element_class_type(query_type, Symbol)
|
18
|
+
|
19
|
+
if params.empty?
|
20
|
+
return query_method(class_method_name, query_type, returns)
|
21
|
+
end
|
22
|
+
|
23
|
+
ParamsValidator.validate(params)
|
24
|
+
query_keyword_method(class_method_name, query_type, params, returns)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_raw_query(params: [], **method_to_raw_query)
|
28
|
+
class_method_name = method_to_raw_query.first[0]
|
29
|
+
query_string = method_to_raw_query.first[1]
|
30
|
+
ClassMethodValidator.validate_class_method(class_method_name, self)
|
31
|
+
ClassMethodValidator.validate_element_class_type(query_string, String)
|
32
|
+
|
33
|
+
if params.empty?
|
34
|
+
return raw_query_method(class_method_name, query_string)
|
35
|
+
end
|
36
|
+
|
37
|
+
ParamsValidator.validate(params)
|
38
|
+
raw_query_keyword_method(class_method_name, query_string, params)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def query_method(class_method_name, query_type, return_fields)
|
44
|
+
define_singleton_method class_method_name do
|
45
|
+
http_client.query(query_type, {}, return_fields.to_a)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def raw_query_method(class_method_name, query_string)
|
50
|
+
define_singleton_method class_method_name do
|
51
|
+
http_client.raw_query(query_string)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def query_keyword_method(name, query_type, keywords, return_fields)
|
56
|
+
keywords = [keywords].flatten
|
57
|
+
instance_eval <<-METHOD, __FILE__, __LINE__ + 1
|
58
|
+
def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
|
59
|
+
http_client.query("#{query_type}",
|
60
|
+
#{CONDITIONS},
|
61
|
+
#{return_fields.to_a})
|
62
|
+
end
|
63
|
+
METHOD
|
64
|
+
end
|
65
|
+
|
66
|
+
def raw_query_keyword_method(name, query_string, keywords)
|
67
|
+
keywords = [keywords].flatten
|
68
|
+
instance_eval <<-METHOD, __FILE__, __LINE__ + 1
|
69
|
+
def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
|
70
|
+
http_client.raw_query("#{query_string}", variables: #{CONDITIONS})
|
71
|
+
end
|
72
|
+
METHOD
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlConnector
|
4
|
+
module ServiceClassable
|
5
|
+
class ReturnFieldsErrors < StandardError; end
|
6
|
+
# Valdations for return fields set within the context of a service class
|
7
|
+
class ReturnFieldsValidator
|
8
|
+
class << self
|
9
|
+
def validate(return_fields)
|
10
|
+
unless return_fields.is_a?(Array)
|
11
|
+
raise ReturnFieldsErrors, 'Please ensure that returns is followed '\
|
12
|
+
'by an array. E.g. returns: [:id]'
|
13
|
+
end
|
14
|
+
|
15
|
+
return_fields.each { |entry| recursive_validation(entry) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def recursive_validation(entry)
|
21
|
+
case entry
|
22
|
+
when Hash
|
23
|
+
hash_validation(entry)
|
24
|
+
when Array
|
25
|
+
entry.each { |item| recursive_validation(item) }
|
26
|
+
else
|
27
|
+
return if [String, Symbol].member?(entry.class)
|
28
|
+
|
29
|
+
raise ReturnFieldsErrors, "The #{entry} is neither a String nor a"\
|
30
|
+
'Symbol!'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def hash_validation(hash)
|
35
|
+
hash.each do |key, value|
|
36
|
+
recursive_validation(key)
|
37
|
+
recursive_validation(value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_connector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garllon
|
8
|
+
- sushie1984
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2020-
|
12
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: httparty
|
@@ -94,10 +95,11 @@ dependencies:
|
|
94
95
|
- - "~>"
|
95
96
|
- !ruby/object:Gem::Version
|
96
97
|
version: '0.75'
|
97
|
-
description:
|
98
|
-
|
98
|
+
description: Grahql client to query with your own raw string, with the small helper
|
99
|
+
method query or with service class inclusion.
|
99
100
|
email:
|
100
101
|
- palluthe.bennet@gmail.com
|
102
|
+
- sascha_burku@yahoo.de
|
101
103
|
executables: []
|
102
104
|
extensions: []
|
103
105
|
extra_rdoc_files: []
|
@@ -114,6 +116,9 @@ files:
|
|
114
116
|
- LICENSE.txt
|
115
117
|
- README.md
|
116
118
|
- bin/console
|
119
|
+
- examples/departments_service_class_examples.rb
|
120
|
+
- examples/query_examples.rb
|
121
|
+
- examples/raw_query_examples.rb
|
117
122
|
- graphql_connector.gemspec
|
118
123
|
- lib/graphql_connector.rb
|
119
124
|
- lib/graphql_connector/base_server_type.rb
|
@@ -121,6 +126,10 @@ files:
|
|
121
126
|
- lib/graphql_connector/custom_attribute_error.rb
|
122
127
|
- lib/graphql_connector/http_client.rb
|
123
128
|
- lib/graphql_connector/query_builder.rb
|
129
|
+
- lib/graphql_connector/service_classable/class_method_validator.rb
|
130
|
+
- lib/graphql_connector/service_classable/params_validator.rb
|
131
|
+
- lib/graphql_connector/service_classable/queryable.rb
|
132
|
+
- lib/graphql_connector/service_classable/return_fields_validator.rb
|
124
133
|
- lib/graphql_connector/version.rb
|
125
134
|
homepage: https://github.com/Garllon/graphql_connector/blob/master/README.md
|
126
135
|
licenses:
|
@@ -147,5 +156,5 @@ requirements: []
|
|
147
156
|
rubygems_version: 3.0.6
|
148
157
|
signing_key:
|
149
158
|
specification_version: 4
|
150
|
-
summary:
|
159
|
+
summary: GraphQL client
|
151
160
|
test_files: []
|