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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b8c2af2590f1daf462e0f348e64078c530a4c7f6833a7d8692e6bada0f11291
4
- data.tar.gz: 52edb3725223b2538f91b1904fa57a071ab0b43b853f37f23242e1dbb8d7eb50
3
+ metadata.gz: 81e604778c1aab26ebebc224ef71b2843f91bc3b51f7098066cb515f9437d300
4
+ data.tar.gz: 9d0f5e40ed50fbcd52974dba215ffda51678a2d334f8fa8321b720d554e683fb
5
5
  SHA512:
6
- metadata.gz: c82b787552cf4590bae68e4eb15103252a47660ba4a8b2d7645deb9e218034cadbca24feaf9ef610818106e322fc7916a91fdd3726d251e49c0051224666d3c2
7
- data.tar.gz: 491988a32bc66f1d597d32dbf0164b5f5a23a87923ac6d4da3c0fbc8272de1b6721ba8657b35e99ad221a9bcb2860431964e22281fcba341da36f3f5dd49ba1e
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.
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: ['2.4.10', '2.5.9', '2.6.7', '2.7.3', '3.0.1']
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
- - uses: actions/checkout@v2
28
- - uses: ruby/setup-ruby@v1
29
- with:
30
- ruby-version: 2.7.3
31
- - name: Install dependencies
32
- run: |
33
- gem install bundler
34
- bundle install
35
- - name: Build and test
36
- run: |
37
- bundle exec rubocop
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
@@ -1,2 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
+ AllCops:
4
+ TargetRubyVersion: 2.4
5
+
6
+ Layout/LineLength:
7
+ Max: 100
data/.rubocop_todo.yml CHANGED
@@ -3,4 +3,5 @@ Lint/DuplicateMethods:
3
3
  - lib/graphql_connector.rb
4
4
  Metrics/BlockLength:
5
5
  Exclude:
6
+ - "*.gemspec"
6
7
  - spec/graphql_connector/**/*.rb
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.3.0)
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.3)
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.9.0)
31
- rspec-core (~> 3.9.0)
32
- rspec-expectations (~> 3.9.0)
33
- rspec-mocks (~> 3.9.0)
34
- rspec-core (3.9.1)
35
- rspec-support (~> 3.9.1)
36
- rspec-expectations (3.9.1)
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.9.0)
39
- rspec-mocks (3.9.1)
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.9.0)
42
- rspec-support (3.9.2)
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.1.4
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
  [![CI](https://github.com/Garllon/graphql_connector/workflows/CI/badge.svg)](https://github.com/Garllon/graphql_connector/actions?query=workflow%3ACI)
7
7
  [![Maintainability](https://api.codeclimate.com/v1/badges/548db3cf0d078b379c84/maintainability)](https://codeclimate.com/github/Garllon/graphql_connector/maintainability)
8
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/548db3cf0d078b379c84/test_coverage)](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
- The connector is expecting that it contains a `base` connector instance and a
38
- `method` parameter as string, where it gets the token. WE expect that the
39
- method is a public method in your connector class. Currently like this:
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: TokenAgent.new, method: 'get_authorization_header' }
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 TokenAgent
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(query_string)
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(model, condition, selected_fields)
105
+ GraphqlConnector::<name>.query('products', { id: [1,2] } , ['id','name'])
87
106
  ```
88
107
 
89
- | Variable | DataType | Example |
90
- |----------------|-------------------------|------------------------------------------|
91
- | model | String | 'product' |
92
- | condition | Hash(key, value) | { id: 1 } |
93
- | selected_fields | Array of Strings/Hashes | ['id', 'name', productCategory: ['id']] |
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
- > Caution:
96
- > You get an OpenStruct back. Currently only the first level attributes are
97
- > supported with OpenStruct, associated objects are still a normal array of
98
- > hashes.
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 <alias>: :<graphql_server_type>, params: [...], returns: [...]
154
+ add_query products_by: :products, params: [:id], returns: [:id, :name]
133
155
 
134
- add_raw_query <alias>: 'query { ... }', params: [...]
156
+ add_raw_query products_raw_by: 'query { products(($id: [ID!]) products { id name } }', params: [:id]
135
157
 
136
- add_mutation <alias>: :<graphql_server_type>, params: [...], returns: [...]
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
@@ -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
- GraphqlConnector::HttpClient.new(@uri, @headers, @connector)
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
- Formatters::QueryFormat.new(model, conditions, selected_fields).create
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
- Formatters::MutationFormat.new(model, inputs, selected_fields).create
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
- variables: variables })
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(response_body)
46
- return OpenStruct.new(response_body) unless response_body.is_a? Array
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
- response_body.map { |entry| OpenStruct.new(entry) }
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
- CONDITIONS = 'binding.local_variables.map do |var|
9
- [var, binding.local_variable_get(var)]
10
- end.to_h'
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.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)
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
- if params.empty?
20
- return query_method(class_method_name, query_type, returns)
21
- end
15
+ ensure_params_format!(returns, class_method_name, query_type)
16
+ ParamsValidator.validate(params) unless params.empty?
22
17
 
23
- ParamsValidator.validate(params)
24
- query_keyword_method(class_method_name, query_type, params, returns)
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.first[0]
29
- query_string = method_to_raw_query.first[1]
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
- 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)
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.first[0]
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
- if params.empty?
49
- return mutation_method(class_method_name, query_type, returns)
50
- end
37
+ ensure_params_format!(returns, class_method_name, query_type)
38
+ ParamsValidator.validate(params) unless params.empty?
51
39
 
52
- ParamsValidator.validate(params)
53
- mutation_keyword_method(class_method_name, query_type, params, returns)
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 query_method(class_method_name, query_type, return_fields)
59
- define_singleton_method class_method_name do
60
- http_client.query(query_type, {}, return_fields.to_a)
61
- end
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 raw_query_method(class_method_name, query_string)
65
- define_singleton_method class_method_name do
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
- instance_eval <<-METHOD, __FILE__, __LINE__ + 1
73
- def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
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 raw_query_keyword_method(name, query_string, keywords)
82
- keywords = [keywords].flatten
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 #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
85
- http_client.raw_query("#{query_string}", variables: #{CONDITIONS})
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 mutation_method(class_method_name, query_type, return_fields)
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 #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
100
- http_client.mutation("#{query_type}",
101
- #{CONDITIONS},
102
- #{return_fields.to_a})
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlConnector
4
- VERSION = '1.3.1'
4
+ VERSION = '2.0.0'
5
5
  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: 1.3.1
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: 2021-06-04 00:00:00.000000000 Z
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: '0'
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.2.7
161
+ rubygems_version: 3.4.1
146
162
  signing_key:
147
163
  specification_version: 4
148
164
  summary: GraphQL client