graphql_connector 1.3.1 → 2.0.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/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yaml +33 -12
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +22 -14
- data/README.md +61 -26
- data/graphql_connector.gemspec +3 -0
- data/lib/graphql_connector/base_server_type.rb +9 -6
- data/lib/graphql_connector/configuration.rb +2 -2
- data/lib/graphql_connector/http_client.rb +31 -17
- data/lib/graphql_connector/service_classable/queryable.rb +49 -67
- data/lib/graphql_connector/version.rb +1 -1
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81e604778c1aab26ebebc224ef71b2843f91bc3b51f7098066cb515f9437d300
|
4
|
+
data.tar.gz: 9d0f5e40ed50fbcd52974dba215ffda51678a2d334f8fa8321b720d554e683fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc5edb75f96dbf575d2bef6e70d7d0980a02c5c7071df2960e40a83f113ad7c85060da3bbd50885c46ac4dbc86306f8db5394a476839a66132c994de0b50925d
|
7
|
+
data.tar.gz: d4737485bc2f8c94db473f605f19e33d570aa5688a90230ee81284980c59b76991290ebef57a446ae8a93ceaf8c26983e96b49e86f48d6e4f9b4878d1d971615
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Describe the bug**
|
11
|
+
A clear and concise description of what the bug is.
|
12
|
+
|
13
|
+
**To Reproduce**
|
14
|
+
Steps to reproduce the behavior:
|
15
|
+
1. Go to '...'
|
16
|
+
2. Click on '....'
|
17
|
+
3. Scroll down to '....'
|
18
|
+
4. See error
|
19
|
+
|
20
|
+
**Expected behavior**
|
21
|
+
A clear and concise description of what you expected to happen.
|
22
|
+
|
23
|
+
**Screenshots**
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
25
|
+
|
26
|
+
**Desktop (please complete the following information):**
|
27
|
+
- OS: [e.g. iOS]
|
28
|
+
- Browser [e.g. chrome, safari]
|
29
|
+
- Version [e.g. 22]
|
30
|
+
|
31
|
+
**Smartphone (please complete the following information):**
|
32
|
+
- Device: [e.g. iPhone6]
|
33
|
+
- OS: [e.g. iOS8.1]
|
34
|
+
- Browser [e.g. stock browser, safari]
|
35
|
+
- Version [e.g. 22]
|
36
|
+
|
37
|
+
**Additional context**
|
38
|
+
Add any other context about the problem here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
12
|
+
|
13
|
+
**Describe the solution you'd like**
|
14
|
+
A clear and concise description of what you want to happen.
|
15
|
+
|
16
|
+
**Describe alternatives you've considered**
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
18
|
+
|
19
|
+
**Additional context**
|
20
|
+
Add any other context or screenshots about the feature request here.
|
data/.github/workflows/ci.yaml
CHANGED
@@ -7,7 +7,7 @@ jobs:
|
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: ['2.
|
10
|
+
ruby: ['2.5', '2.6', '2.7', '3.0', '3.1']
|
11
11
|
name: "ruby ${{ matrix.ruby }}"
|
12
12
|
steps:
|
13
13
|
- uses: actions/checkout@v1
|
@@ -24,14 +24,35 @@ jobs:
|
|
24
24
|
name: Rubocop
|
25
25
|
runs-on: ubuntu-latest
|
26
26
|
steps:
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
27
|
+
- uses: actions/checkout@v2
|
28
|
+
- uses: ruby/setup-ruby@v1
|
29
|
+
with:
|
30
|
+
ruby-version: 2.7
|
31
|
+
- name: Install dependencies
|
32
|
+
run: |
|
33
|
+
gem install bundler
|
34
|
+
bundle install
|
35
|
+
- name: Build and test
|
36
|
+
run: |
|
37
|
+
bundle exec rubocop
|
38
|
+
coverage:
|
39
|
+
name: coverage
|
40
|
+
runs-on: ubuntu-latest
|
41
|
+
steps:
|
42
|
+
- uses: actions/checkout@v1
|
43
|
+
- uses: ruby/setup-ruby@v1
|
44
|
+
with:
|
45
|
+
ruby-version: 2.7
|
46
|
+
- name: Setup Code Climate test-reporter
|
47
|
+
run: |
|
48
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
49
|
+
chmod +x ./cc-test-reporter
|
50
|
+
./cc-test-reporter before-build
|
51
|
+
- name: Build and test with RSpec
|
52
|
+
run: |
|
53
|
+
gem install bundler
|
54
|
+
bundle install
|
55
|
+
bundle exec rspec
|
56
|
+
- name: Publish code coverage
|
57
|
+
run: |
|
58
|
+
./cc-test-reporter after-build -r ${{ secrets.CC_TEST_REPORTER_ID }}
|
data/.gitignore
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
coverage/**
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 2.0.0 (TBD)
|
2
|
+
|
3
|
+
### Features
|
4
|
+
|
5
|
+
Write here
|
6
|
+
|
7
|
+
### Breaking changes
|
8
|
+
|
9
|
+
* query results are now transformed to OpenStructs recursively, so nested attributes are no longer a hash but another OpenStruct
|
10
|
+
* Set minimum Ruby version to `2.4` or higher
|
11
|
+
|
12
|
+
## 1.4.0 (2022-03-17)
|
13
|
+
|
14
|
+
* Add config for `httparty_adapter_options` allowing forwarding options to `httparty`
|
15
|
+
|
1
16
|
## 1.3.1 (2021-06-04)
|
2
17
|
|
3
18
|
* add more specs to test headers and connectors
|
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.4.0)
|
5
5
|
httparty (~> 0.16)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,7 +9,8 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
ast (2.4.0)
|
11
11
|
coderay (1.1.2)
|
12
|
-
diff-lcs (1.
|
12
|
+
diff-lcs (1.5.0)
|
13
|
+
docile (1.4.0)
|
13
14
|
httparty (0.18.1)
|
14
15
|
mime-types (~> 3.0)
|
15
16
|
multi_xml (>= 0.5.2)
|
@@ -27,19 +28,19 @@ GEM
|
|
27
28
|
method_source (~> 1.0)
|
28
29
|
rainbow (3.0.0)
|
29
30
|
rexml (3.2.5)
|
30
|
-
rspec (3.
|
31
|
-
rspec-core (~> 3.
|
32
|
-
rspec-expectations (~> 3.
|
33
|
-
rspec-mocks (~> 3.
|
34
|
-
rspec-core (3.
|
35
|
-
rspec-support (~> 3.
|
36
|
-
rspec-expectations (3.
|
31
|
+
rspec (3.11.0)
|
32
|
+
rspec-core (~> 3.11.0)
|
33
|
+
rspec-expectations (~> 3.11.0)
|
34
|
+
rspec-mocks (~> 3.11.0)
|
35
|
+
rspec-core (3.11.0)
|
36
|
+
rspec-support (~> 3.11.0)
|
37
|
+
rspec-expectations (3.11.0)
|
37
38
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
-
rspec-support (~> 3.
|
39
|
-
rspec-mocks (3.
|
39
|
+
rspec-support (~> 3.11.0)
|
40
|
+
rspec-mocks (3.11.0)
|
40
41
|
diff-lcs (>= 1.2.0, < 2.0)
|
41
|
-
rspec-support (~> 3.
|
42
|
-
rspec-support (3.
|
42
|
+
rspec-support (~> 3.11.0)
|
43
|
+
rspec-support (3.11.0)
|
43
44
|
rubocop (0.82.0)
|
44
45
|
jaro_winkler (~> 1.5.1)
|
45
46
|
parallel (~> 1.10)
|
@@ -49,6 +50,12 @@ GEM
|
|
49
50
|
ruby-progressbar (~> 1.7)
|
50
51
|
unicode-display_width (>= 1.4.0, < 2.0)
|
51
52
|
ruby-progressbar (1.10.1)
|
53
|
+
simplecov (0.21.2)
|
54
|
+
docile (~> 1.1)
|
55
|
+
simplecov-html (~> 0.11)
|
56
|
+
simplecov_json_formatter (~> 0.1)
|
57
|
+
simplecov-html (0.12.3)
|
58
|
+
simplecov_json_formatter (0.1.4)
|
52
59
|
unicode-display_width (1.7.0)
|
53
60
|
|
54
61
|
PLATFORMS
|
@@ -60,6 +67,7 @@ DEPENDENCIES
|
|
60
67
|
pry (~> 0.10)
|
61
68
|
rspec (~> 3.8)
|
62
69
|
rubocop (~> 0.75)
|
70
|
+
simplecov (~> 0.21.2)
|
63
71
|
|
64
72
|
BUNDLED WITH
|
65
|
-
2.
|
73
|
+
2.3.9
|
data/README.md
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
Version](https://badge.fury.io/rb/graphql_connector.svg)](https://badge.fury.io/rb/graphql_connector)
|
6
6
|
[](https://github.com/Garllon/graphql_connector/actions?query=workflow%3ACI)
|
7
7
|
[](https://codeclimate.com/github/Garllon/graphql_connector/maintainability)
|
8
|
+
[](https://codeclimate.com/github/Garllon/graphql_connector/test_coverage)
|
8
9
|
|
9
10
|
An easy connector to call your `graphql` server. Currently there is no schema
|
10
11
|
check in the code, but i will add it.
|
@@ -30,20 +31,21 @@ Or install it yourself as:
|
|
30
31
|
You need to configure the `graphql_connector` first:
|
31
32
|
``` ruby
|
32
33
|
GraphqlConnector.configure do |config|
|
33
|
-
config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {})
|
34
|
+
config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {}, connector: {}, httparty_adapter_options: {})
|
34
35
|
end
|
35
36
|
```
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
* `name` (**mandatory**): Add a namespace under which the API is reachable. In the above example `'Foo'` means that `GraphqlConnector::Foo` provides API functionality for the configured `add_server`
|
39
|
+
|
40
|
+
* `uri` (**mandatory**): Add uri of grapqhl API server that accepts **POST** requests.
|
41
|
+
|
42
|
+
* `connector` (**optionally**): Add a **Authentication Token class** in the following format:
|
40
43
|
```ruby
|
41
|
-
{ base:
|
44
|
+
connector: { base: AuthTokenAgent.instance, method: 'get_authorization_header' }
|
42
45
|
```
|
43
|
-
|
44
|
-
Your method should return a hash like this:
|
46
|
+
`base` is an instance of Authentication Token class and `method` represents the function where it gets the token.
|
45
47
|
```ruby
|
46
|
-
class
|
48
|
+
class AuthTokenAgent
|
47
49
|
[...]
|
48
50
|
def get_authorization_header
|
49
51
|
[...]
|
@@ -51,9 +53,12 @@ class TokenAgent
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
```
|
56
|
+
:warning: The function under `method` must be a public one in your connector class.<br />
|
57
|
+
:warning: When you set a connector, it will override the setting in the headers for Authorization.
|
58
|
+
|
59
|
+
|
60
|
+
* `httparty_adapter_options` (**optionally**): Add any [`connection_adapter`](https://github.com/jnunemaker/httparty/blob/master/lib/httparty/connection_adapter.rb) options that `httparty` supports in a hash format e.g. `{ timeout: 4 }`
|
54
61
|
|
55
|
-
When you set a connector, it will override the setting in the headers for
|
56
|
-
Authorization.
|
57
62
|
|
58
63
|
For each graphql server you wish to query use `add_server`.
|
59
64
|
|
@@ -71,9 +76,23 @@ See the following sub sections for details
|
|
71
76
|
|
72
77
|
You can call your graphql_endpoint via:
|
73
78
|
```ruby
|
74
|
-
GraphqlConnector::<name>.raw_query(
|
79
|
+
GraphqlConnector::<name>.raw_query('query { products { id name } }')
|
80
|
+
|
81
|
+
GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 })
|
82
|
+
|
83
|
+
GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }')
|
84
|
+
```
|
85
|
+
|
86
|
+
Or if you want to **override**/**set** any `httparty_adapter_options` it is also possible to pass them in:
|
87
|
+
```ruby
|
88
|
+
GraphqlConnector::<name>.raw_query('query { products { id name } }', httparty_adapter_options: { timeout: 3, verify: true })
|
89
|
+
|
90
|
+
GraphqlConnector::<name>.raw_query('query { products($id: [ID!]) { products(id: $id) { id name } } }', variables: { id: 1 }, httparty_adapter_options: { timeout: 3, verify: true })
|
91
|
+
|
92
|
+
GraphqlConnector::<name>.raw_query('mutation { createProduct(name: "Coca-Cola") { id name } }', httparty_adapter_options: { timeout: 3, verify: true })
|
75
93
|
```
|
76
94
|
|
95
|
+
|
77
96
|
Note that `<name>` has to be replaced by any of the ones added via `add_server`
|
78
97
|
|
79
98
|
See also [here](examples/raw_query_examples.rb) for example usage
|
@@ -83,19 +102,22 @@ See also [here](examples/raw_query_examples.rb) for example usage
|
|
83
102
|
|
84
103
|
You can also use the more comfortable `query`:
|
85
104
|
```ruby
|
86
|
-
GraphqlConnector::<name>.query(
|
105
|
+
GraphqlConnector::<name>.query('products', { id: [1,2] } , ['id','name'])
|
87
106
|
```
|
88
107
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
108
|
+
Or if you want to **override**/**set** any `httparty` adapter_options, it is also possible
|
109
|
+
to pass them in:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
GraphqlConnector::<name>.query('products', { id: [1,2] } , ['id','name'], httparty_adapter_options: { timeout: 3 })
|
113
|
+
```
|
94
114
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
115
|
+
| Variable | Required | DataType | Example |
|
116
|
+
|--------------------------|-------------------------------|-------------------------|-----------------------------------------|
|
117
|
+
| model | Yes | String | 'product' |
|
118
|
+
| condition | Yes (but can be empty) | Hash(key, value) | { id: 1 } |
|
119
|
+
| selected_fields | Yes | Array of Strings/Hashes | ['id', 'name', productCategory: ['id']] |
|
120
|
+
| httparty_adapter_options | No | Hash | { timeout: 3 } |
|
99
121
|
|
100
122
|
See also [here](examples/query_examples.rb) for example usage
|
101
123
|
|
@@ -129,14 +151,25 @@ so that it has re-usable graphql `query` and `mutation` **class methods**.
|
|
129
151
|
* Then you can aliases as many graphql server types via `add_query` and/or `add_raw_query` and/or `add_mutation`:
|
130
152
|
|
131
153
|
```ruby
|
132
|
-
add_query
|
154
|
+
add_query products_by: :products, params: [:id], returns: [:id, :name]
|
133
155
|
|
134
|
-
add_raw_query
|
156
|
+
add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id]
|
135
157
|
|
136
|
-
add_mutation
|
158
|
+
add_mutation create: :createProduct, params: [:name], returns: [:id, :name]
|
137
159
|
```
|
138
160
|
* :grey_exclamation: If not needed omit `params`
|
139
161
|
|
162
|
+
Or if you want to **override**/**set** any `httparty` adapter_options, it is also possible
|
163
|
+
to pass them in:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
add_query products_by: :products, params: [:id], returns: [:id, :name], httparty_adapter_options: { timeout: 3 }
|
167
|
+
|
168
|
+
add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id], httparty_adapter_options: { verify: true }
|
169
|
+
|
170
|
+
add_mutation create: :createProduct, params: [:name], returns: [:id, :name], httparty_adapter_options: { timeout: 5, verify: false }
|
171
|
+
```
|
172
|
+
|
140
173
|
See also [here](examples/departments_service_class_examples.rb) and also here for complete example usage:
|
141
174
|
|
142
175
|
```ruby
|
@@ -153,7 +186,8 @@ class Product
|
|
153
186
|
|
154
187
|
add_query by_id: :products,
|
155
188
|
params: :id,
|
156
|
-
returns: [:name, product_category: [:id, :name]]
|
189
|
+
returns: [:name, product_category: [:id, :name]],
|
190
|
+
httparty_adapter_options: { timeout: 3 }
|
157
191
|
|
158
192
|
add_query by_names: :products,
|
159
193
|
params: :names,
|
@@ -169,7 +203,8 @@ class Product
|
|
169
203
|
|
170
204
|
add_mutation create: :createProduct,
|
171
205
|
params: [:name, :catgetoryId],
|
172
|
-
returns: [:id, :name]
|
206
|
+
returns: [:id, :name],
|
207
|
+
httparty_adapter_options: { verify: false }
|
173
208
|
end
|
174
209
|
|
175
210
|
Product.all
|
data/graphql_connector.gemspec
CHANGED
@@ -31,10 +31,13 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ['lib']
|
33
33
|
|
34
|
+
spec.required_ruby_version = '>= 2.4.0'
|
35
|
+
|
34
36
|
spec.add_dependency 'httparty', '~> 0.16'
|
35
37
|
|
36
38
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
37
39
|
spec.add_development_dependency 'pry', '~> 0.10'
|
38
40
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
39
41
|
spec.add_development_dependency 'rubocop', '~> 0.75'
|
42
|
+
spec.add_development_dependency 'simplecov', '~> 0.21.2'
|
40
43
|
end
|
@@ -5,9 +5,9 @@ module GraphqlConnector
|
|
5
5
|
# Class to wrap http_client calls under a specific namespaced class
|
6
6
|
class BaseServerType
|
7
7
|
class << self
|
8
|
-
def build(name, uri, headers = {}, connector = {})
|
8
|
+
def build(name, uri, headers = {}, connector = {}, httparty_adapter_options = {})
|
9
9
|
verify_new_client_type_for!(name)
|
10
|
-
base_class = class_with(uri, headers, connector)
|
10
|
+
base_class = class_with(uri, headers, connector, httparty_adapter_options)
|
11
11
|
base_object = GraphqlConnector.const_set(name, base_class)
|
12
12
|
inject_http_client_delegations(base_object)
|
13
13
|
create_service_class_module(base_object)
|
@@ -39,12 +39,13 @@ module GraphqlConnector
|
|
39
39
|
METHOD
|
40
40
|
end
|
41
41
|
|
42
|
-
def class_with(uri, headers = {}, connector = {})
|
42
|
+
def class_with(uri, headers = {}, connector = {}, httparty_adapter_options = {})
|
43
43
|
Class.new do
|
44
|
-
attr_accessor :uri, :headers, :connector
|
44
|
+
attr_accessor :uri, :headers, :connector, :httparty_adapter_options
|
45
45
|
@uri = uri
|
46
46
|
@headers = headers
|
47
47
|
@connector = connector
|
48
|
+
@httparty_adapter_options = httparty_adapter_options
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -54,8 +55,10 @@ module GraphqlConnector
|
|
54
55
|
def_delegators :http_client, :query, :raw_query, :mutation
|
55
56
|
|
56
57
|
def http_client
|
57
|
-
@http_client ||=
|
58
|
-
|
58
|
+
@http_client ||= GraphqlConnector::HttpClient.new(@uri,
|
59
|
+
@headers,
|
60
|
+
@connector,
|
61
|
+
@httparty_adapter_options)
|
59
62
|
end
|
60
63
|
end
|
61
64
|
end
|
@@ -9,9 +9,9 @@ module GraphqlConnector
|
|
9
9
|
@base_server_types = {}
|
10
10
|
end
|
11
11
|
|
12
|
-
def add_server(name:, uri:, headers: {}, connector: {})
|
12
|
+
def add_server(name:, uri:, headers: {}, connector: {}, httparty_adapter_options: {})
|
13
13
|
@base_server_types[name] =
|
14
|
-
BaseServerType.build(name, uri, headers, connector)
|
14
|
+
BaseServerType.build(name, uri, headers, connector, httparty_adapter_options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def reset!
|
@@ -3,31 +3,29 @@
|
|
3
3
|
module GraphqlConnector
|
4
4
|
# Wrapper class for HTTParty post query
|
5
5
|
class HttpClient
|
6
|
-
def initialize(uri, headers = {}, connector = {})
|
6
|
+
def initialize(uri, headers = {}, connector = {}, httparty_adapter_options = {})
|
7
7
|
@uri = uri
|
8
8
|
@headers = headers
|
9
9
|
@connector = connector
|
10
|
+
@httparty_adapter_options = httparty_adapter_options
|
10
11
|
end
|
11
12
|
|
12
|
-
def query(model, conditions, selected_fields)
|
13
|
-
query_string =
|
14
|
-
|
15
|
-
parsed_body = raw_query(query_string)
|
16
|
-
format_body(parsed_body['data'][model.to_s])
|
13
|
+
def query(model, conditions, selected_fields, httparty_adapter_options: {})
|
14
|
+
query_string = Formatters::QueryFormat.new(model, conditions, selected_fields).create
|
15
|
+
format_body(query_string, model, httparty_adapter_options)
|
17
16
|
end
|
18
17
|
|
19
|
-
def mutation(model, inputs, selected_fields)
|
20
|
-
query_string =
|
21
|
-
|
22
|
-
parsed_body = raw_query(query_string)
|
23
|
-
format_body(parsed_body['data'][model.to_s])
|
18
|
+
def mutation(model, inputs, selected_fields, httparty_adapter_options: {})
|
19
|
+
query_string = Formatters::MutationFormat.new(model, inputs, selected_fields).create
|
20
|
+
format_body(query_string, model, httparty_adapter_options)
|
24
21
|
end
|
25
22
|
|
26
|
-
def raw_query(query_string, variables: {})
|
23
|
+
def raw_query(query_string, variables: {}, httparty_adapter_options: {})
|
24
|
+
adapter_options = combined_adapter_options(httparty_adapter_options)
|
27
25
|
response = HTTParty.post(@uri,
|
28
26
|
headers: handle_headers,
|
29
|
-
body: { query: query_string,
|
30
|
-
|
27
|
+
body: { query: query_string, variables: variables },
|
28
|
+
**adapter_options)
|
31
29
|
parsed_body = JSON.parse(response.body)
|
32
30
|
verify_response!(parsed_body)
|
33
31
|
parsed_body
|
@@ -35,6 +33,10 @@ module GraphqlConnector
|
|
35
33
|
|
36
34
|
private
|
37
35
|
|
36
|
+
def combined_adapter_options(options)
|
37
|
+
@httparty_adapter_options.merge(options)
|
38
|
+
end
|
39
|
+
|
38
40
|
def handle_headers
|
39
41
|
return @headers if @connector.empty?
|
40
42
|
|
@@ -42,10 +44,22 @@ module GraphqlConnector
|
|
42
44
|
.merge(@connector[:base].public_send(@connector[:method]))
|
43
45
|
end
|
44
46
|
|
45
|
-
def format_body(
|
46
|
-
|
47
|
+
def format_body(query_string, model, httparty_adapter_options)
|
48
|
+
parsed_body = raw_query(query_string, httparty_adapter_options: httparty_adapter_options)
|
49
|
+
response_body = parsed_body['data'][model.to_s]
|
50
|
+
transform_data(response_body)
|
51
|
+
end
|
47
52
|
|
48
|
-
|
53
|
+
def transform_data(data)
|
54
|
+
case data
|
55
|
+
when Array
|
56
|
+
data.map { |element| transform_data(element) }
|
57
|
+
when Hash
|
58
|
+
data = data.transform_values { |value| transform_data(value) }
|
59
|
+
OpenStruct.new(data)
|
60
|
+
else
|
61
|
+
data
|
62
|
+
end
|
49
63
|
end
|
50
64
|
|
51
65
|
def verify_response!(parsed_body)
|
@@ -5,101 +5,83 @@ module GraphqlConnector
|
|
5
5
|
# Module that allows to build query methods within the context of
|
6
6
|
# service class
|
7
7
|
module Queryable
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
BINDINGS = 'binding.local_variables.map do |var|
|
9
|
+
[var, binding.local_variable_get(var)]
|
10
|
+
end.to_h'
|
11
11
|
|
12
|
-
def add_query(params: [], returns:, **method_to_query)
|
13
|
-
class_method_name = method_to_query
|
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)
|
12
|
+
def add_query(params: [], httparty_adapter_options: {}, returns:, **method_to_query)
|
13
|
+
class_method_name, query_type = parse_variables(method_to_query)
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
15
|
+
ensure_params_format!(returns, class_method_name, query_type)
|
16
|
+
ParamsValidator.validate(params) unless params.empty?
|
22
17
|
|
23
|
-
|
24
|
-
|
18
|
+
signature = method_signature(class_method_name, params)
|
19
|
+
signature[:graphql_method_type] = :query
|
20
|
+
create_method(signature, query_type, returns, httparty_adapter_options)
|
25
21
|
end
|
26
22
|
|
27
|
-
def add_raw_query(params: [], **method_to_raw_query)
|
28
|
-
class_method_name = method_to_raw_query
|
29
|
-
|
23
|
+
def add_raw_query(params: [], httparty_adapter_options: {}, **method_to_raw_query)
|
24
|
+
class_method_name, query_string = parse_variables(method_to_raw_query)
|
25
|
+
|
30
26
|
ClassMethodValidator.validate_class_method(class_method_name, self)
|
31
27
|
ClassMethodValidator.validate_element_class_type(query_string, String)
|
28
|
+
ParamsValidator.validate(params) unless params.empty?
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
ParamsValidator.validate(params)
|
38
|
-
raw_query_keyword_method(class_method_name, query_string, params)
|
30
|
+
signature = method_signature(class_method_name, params)
|
31
|
+
raw_query_method(signature, query_string, httparty_adapter_options)
|
39
32
|
end
|
40
33
|
|
41
|
-
def add_mutation(params: [], returns:, **method_to_query)
|
42
|
-
class_method_name = method_to_query
|
43
|
-
query_type = method_to_query.first[1]
|
44
|
-
ReturnFieldsValidator.validate(returns)
|
45
|
-
ClassMethodValidator.validate_class_method(class_method_name, self)
|
46
|
-
ClassMethodValidator.validate_element_class_type(query_type, Symbol)
|
34
|
+
def add_mutation(params: [], httparty_adapter_options: {}, returns:, **method_to_query)
|
35
|
+
class_method_name, query_type = parse_variables(method_to_query)
|
47
36
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
37
|
+
ensure_params_format!(returns, class_method_name, query_type)
|
38
|
+
ParamsValidator.validate(params) unless params.empty?
|
51
39
|
|
52
|
-
|
53
|
-
|
40
|
+
signature = method_signature(class_method_name, params)
|
41
|
+
signature[:graphql_method_type] = :mutation
|
42
|
+
create_method(signature, query_type, returns, httparty_adapter_options)
|
54
43
|
end
|
55
44
|
|
56
45
|
private
|
57
46
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
47
|
+
def parse_variables(method_to_query)
|
48
|
+
class_method_name = method_to_query.first[0]
|
49
|
+
query_type = method_to_query.first[1]
|
50
|
+
[class_method_name, query_type]
|
62
51
|
end
|
63
52
|
|
64
|
-
def
|
65
|
-
|
66
|
-
http_client.raw_query(query_string)
|
67
|
-
end
|
68
|
-
end
|
53
|
+
def method_signature(name, keywords)
|
54
|
+
return { head: name, bindings: {} } if keywords.empty?
|
69
55
|
|
70
|
-
def query_keyword_method(name, query_type, keywords, return_fields)
|
71
56
|
keywords = [keywords].flatten
|
72
|
-
|
73
|
-
|
74
|
-
http_client.query("#{query_type}",
|
75
|
-
#{CONDITIONS},
|
76
|
-
#{return_fields.to_a})
|
77
|
-
end
|
78
|
-
METHOD
|
57
|
+
{ head: "#{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})",
|
58
|
+
bindings: BINDINGS }
|
79
59
|
end
|
80
60
|
|
81
|
-
def
|
82
|
-
|
61
|
+
def ensure_params_format!(returns, class_method_name, query_type)
|
62
|
+
ReturnFieldsValidator.validate(returns)
|
63
|
+
ClassMethodValidator.validate_class_method(class_method_name, self)
|
64
|
+
ClassMethodValidator.validate_element_class_type(query_type, Symbol)
|
65
|
+
end
|
66
|
+
|
67
|
+
def raw_query_method(signature, query_string, httparty_adapter_options)
|
83
68
|
instance_eval <<-METHOD, __FILE__, __LINE__ + 1
|
84
|
-
def #{
|
85
|
-
http_client.raw_query("#{query_string}",
|
69
|
+
def #{signature[:head]}
|
70
|
+
http_client.raw_query("#{query_string}",
|
71
|
+
variables: #{signature[:bindings]},
|
72
|
+
httparty_adapter_options: #{httparty_adapter_options})
|
86
73
|
end
|
87
74
|
METHOD
|
88
75
|
end
|
89
76
|
|
90
|
-
def
|
91
|
-
define_singleton_method class_method_name do
|
92
|
-
http_client.mutation(query_type, {}, return_fields.to_a)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def mutation_keyword_method(name, query_type, keywords, return_fields)
|
97
|
-
keywords = [keywords].flatten
|
77
|
+
def create_method(signature, query_type, return_fields, httparty_adapter_options)
|
98
78
|
instance_eval <<-METHOD, __FILE__, __LINE__ + 1
|
99
|
-
def #{
|
100
|
-
http_client
|
101
|
-
|
102
|
-
|
79
|
+
def #{signature[:head]}
|
80
|
+
http_client.#{signature[:graphql_method_type]}(
|
81
|
+
"#{query_type}",
|
82
|
+
#{signature[:bindings]},
|
83
|
+
#{return_fields.to_a},
|
84
|
+
httparty_adapter_options: #{httparty_adapter_options})
|
103
85
|
end
|
104
86
|
METHOD
|
105
87
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql_connector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garllon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-08-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -81,6 +81,20 @@ dependencies:
|
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0.75'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: simplecov
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.21.2
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 0.21.2
|
84
98
|
description: Grahql client to query with your own raw string, with the small helper
|
85
99
|
method query or with service class inclusion.
|
86
100
|
email:
|
@@ -90,6 +104,8 @@ executables: []
|
|
90
104
|
extensions: []
|
91
105
|
extra_rdoc_files: []
|
92
106
|
files:
|
107
|
+
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
108
|
+
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
93
109
|
- ".github/workflows/ci.yaml"
|
94
110
|
- ".gitignore"
|
95
111
|
- ".rspec"
|
@@ -135,14 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
151
|
requirements:
|
136
152
|
- - ">="
|
137
153
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
154
|
+
version: 2.4.0
|
139
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
156
|
requirements:
|
141
157
|
- - ">="
|
142
158
|
- !ruby/object:Gem::Version
|
143
159
|
version: '0'
|
144
160
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
161
|
+
rubygems_version: 3.4.1
|
146
162
|
signing_key:
|
147
163
|
specification_version: 4
|
148
164
|
summary: GraphQL client
|