client-api-builder 0.1.0 → 0.2.3

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: 34ae348684b22669748f3dca2fc9866f2b87247da8452fc5b848e175c1ef74a8
4
- data.tar.gz: 95e6b09d24e961c0ce20a6cc15d3fcdf858f47b2725151838cd8ea5d01df0965
3
+ metadata.gz: '01795148989ed0a14c42cb886fd3ce76e3692d82c388f49adf09b7b7229b928f'
4
+ data.tar.gz: 4ce828ecc5ee2017e6318ab83e8c1c02e3a557f746a7f3f6fc8d7471cdac2750
5
5
  SHA512:
6
- metadata.gz: e6dd7780a28eec364c787d209fbd37618c6c9f8c7262c1abaa2fbf90b419240657a77bd1a7523388f680643837839162c36a427ca3023ccee986d6f0c1ba3b43
7
- data.tar.gz: 6b407cefa4e351149e881c6f19897f1566b0440684790f26b9df7636a151737c068efd23ced372b8cd0a306179dc6a4c3491de574fdaacdd8b5f90b0b03e5e93
6
+ metadata.gz: 57b713cda946c263a13f6642d8548442f574eaea1f0374b1e02c7d2f071a3826aeb3e49eaa3a785784eeb7caa671584192f0391e6a508b5dbbd4fff32868063e
7
+ data.tar.gz: d41bfea574c3399d534455ab7165a9fc6f91c347fd5c6d6634fa67731bb5198ccc843532e06fea853097316f766522daebf875cce855694b87e67bb0ea6771fb
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.1
1
+ 3.0.0
data/Gemfile.lock CHANGED
@@ -1,60 +1,62 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- addressable (2.7.0)
4
+ addressable (2.8.0)
5
5
  public_suffix (>= 2.0.2, < 5.0)
6
- ast (2.4.1)
6
+ ast (2.4.2)
7
7
  crack (0.4.5)
8
8
  rexml
9
9
  diff-lcs (1.4.4)
10
- docile (1.3.2)
10
+ docile (1.4.0)
11
11
  hashdiff (1.0.1)
12
12
  inheritance-helper (0.1.5)
13
- parallel (1.19.2)
14
- parser (2.7.1.4)
13
+ parallel (1.20.1)
14
+ parser (3.0.1.1)
15
15
  ast (~> 2.4.1)
16
16
  public_suffix (4.0.6)
17
17
  rainbow (3.0.0)
18
- rake (13.0.1)
19
- regexp_parser (1.7.1)
20
- rexml (3.2.4)
21
- rspec (3.9.0)
22
- rspec-core (~> 3.9.0)
23
- rspec-expectations (~> 3.9.0)
24
- rspec-mocks (~> 3.9.0)
25
- rspec-core (3.9.2)
26
- rspec-support (~> 3.9.3)
27
- rspec-expectations (3.9.2)
18
+ rake (13.0.3)
19
+ regexp_parser (2.1.1)
20
+ rexml (3.2.5)
21
+ rspec (3.10.0)
22
+ rspec-core (~> 3.10.0)
23
+ rspec-expectations (~> 3.10.0)
24
+ rspec-mocks (~> 3.10.0)
25
+ rspec-core (3.10.1)
26
+ rspec-support (~> 3.10.0)
27
+ rspec-expectations (3.10.1)
28
28
  diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.9.0)
30
- rspec-mocks (3.9.1)
29
+ rspec-support (~> 3.10.0)
30
+ rspec-mocks (3.10.2)
31
31
  diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.9.0)
33
- rspec-support (3.9.3)
34
- rubocop (0.87.1)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-support (3.10.2)
34
+ rubocop (1.18.2)
35
35
  parallel (~> 1.10)
36
- parser (>= 2.7.1.1)
36
+ parser (>= 3.0.0.0)
37
37
  rainbow (>= 2.2.2, < 4.0)
38
- regexp_parser (>= 1.7)
38
+ regexp_parser (>= 1.8, < 3.0)
39
39
  rexml
40
- rubocop-ast (>= 0.1.0, < 1.0)
40
+ rubocop-ast (>= 1.7.0, < 2.0)
41
41
  ruby-progressbar (~> 1.7)
42
- unicode-display_width (>= 1.4.0, < 2.0)
43
- rubocop-ast (0.1.0)
44
- parser (>= 2.7.0.1)
45
- ruby-progressbar (1.10.1)
46
- simplecov (0.18.5)
42
+ unicode-display_width (>= 1.4.0, < 3.0)
43
+ rubocop-ast (1.7.0)
44
+ parser (>= 3.0.1.1)
45
+ ruby-progressbar (1.11.0)
46
+ simplecov (0.21.2)
47
47
  docile (~> 1.1)
48
48
  simplecov-html (~> 0.11)
49
- simplecov-html (0.12.2)
50
- unicode-display_width (1.7.0)
51
- webmock (3.11.1)
49
+ simplecov_json_formatter (~> 0.1)
50
+ simplecov-html (0.12.3)
51
+ simplecov_json_formatter (0.1.3)
52
+ unicode-display_width (2.0.0)
53
+ webmock (3.13.0)
52
54
  addressable (>= 2.3.6)
53
55
  crack (>= 0.3.2)
54
56
  hashdiff (>= 0.4.0, < 2.0.0)
55
57
 
56
58
  PLATFORMS
57
- ruby
59
+ x86_64-darwin-20
58
60
 
59
61
  DEPENDENCIES
60
62
  inheritance-helper
@@ -65,4 +67,4 @@ DEPENDENCIES
65
67
  webmock
66
68
 
67
69
  BUNDLED WITH
68
- 2.1.4
70
+ 2.2.3
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'client-api-builder'
5
- s.version = '0.1.0'
5
+ s.version = '0.2.3'
6
6
  s.licenses = ['MIT']
7
7
  s.summary = 'Develop Client API libraries faster'
8
8
  s.description = 'Utility for constructing API clients'
@@ -0,0 +1,23 @@
1
+ require 'base64'
2
+
3
+ class BasicAuthExampleClient < Struct.new(
4
+ :username,
5
+ :password
6
+ )
7
+
8
+ include ClientApiBuilder::Router
9
+
10
+ base_url 'https://www.example.com'
11
+
12
+ header 'Authorization', :basic_authorization
13
+ query_param('cache_buster') { (Time.now.to_f * 1000).to_i }
14
+
15
+ route :get_apps, '/apps'
16
+ route :get_app, '/apps/:app_id'
17
+
18
+ private
19
+
20
+ def basic_authorization
21
+ 'basic ' + Base64.strict_encode64(username + ':' + password)
22
+ end
23
+ end
@@ -28,7 +28,30 @@ module ClientApiBuilder
28
28
  request.body = body if body
29
29
 
30
30
  Net::HTTP.start(uri.hostname, uri.port, connection_options.merge(use_ssl: uri.scheme == 'https')) do |http|
31
- http.request(request)
31
+ http.request(request) do |response|
32
+ yield response if block_given?
33
+ end
34
+ end
35
+ end
36
+
37
+ def stream(method:, uri:, body:, headers:, connection_options:)
38
+ request(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options) do |response|
39
+ response.read_body do |chunk|
40
+ yield chunk
41
+ end
42
+ end
43
+ end
44
+
45
+ def stream_to_io(method:, uri:, body:, headers:, connection_options:, io:)
46
+ stream(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options) do |chunk|
47
+ io.write chunk
48
+ end
49
+ end
50
+
51
+ def stream_to_file(method:, uri:, body:, headers:, connection_options:, file:)
52
+ mode = connection_options.delete(:file_mode) || 'wb'
53
+ File.open(file, mode) do |io|
54
+ stream_to_io(method: method, uri: uri, body: body, headers: headers, connection_options: connection_options, io: io)
32
55
  end
33
56
  end
34
57
  end
@@ -7,7 +7,7 @@ module ClientApiBuilder
7
7
  base.extend InheritanceHelper::Methods
8
8
  base.extend ClassMethods
9
9
  base.include ::ClientApiBuilder::NetHTTP::Request
10
- base.attr_reader :response
10
+ base.attr_reader :response, :request_options
11
11
  end
12
12
 
13
13
  module ClassMethods
@@ -22,6 +22,7 @@ module ClientApiBuilder
22
22
  base_url: nil,
23
23
  headers: {},
24
24
  connection_options: {},
25
+ query_params: {},
25
26
  query_builder: Hash.method_defined?(:to_query) ? :to_query : :query_params
26
27
  }.freeze
27
28
  end
@@ -38,9 +39,9 @@ module ClientApiBuilder
38
39
  add_value_to_class_method(:default_options, query_builder: builder)
39
40
  end
40
41
 
41
- def header(name, value)
42
+ def header(name, value = nil, &block)
42
43
  headers = default_options[:headers].dup
43
- headers[name] = value
44
+ headers[name] = value || block
44
45
  add_value_to_class_method(:default_options, headers: headers)
45
46
  end
46
47
 
@@ -50,6 +51,12 @@ module ClientApiBuilder
50
51
  add_value_to_class_method(:default_options, connection_options: connection_options)
51
52
  end
52
53
 
54
+ def query_param(name, value = nil, &block)
55
+ query_params = default_options[:query_params].dup
56
+ query_params[name] = value || block
57
+ add_value_to_class_method(:default_options, query_params: query_params)
58
+ end
59
+
53
60
  def headers
54
61
  default_options[:headers]
55
62
  end
@@ -58,6 +65,10 @@ module ClientApiBuilder
58
65
  default_options[:connection_options]
59
66
  end
60
67
 
68
+ def query_params
69
+ default_options[:query_params]
70
+ end
71
+
61
72
  def build_query(query)
62
73
  case query_builder
63
74
  when :to_query
@@ -181,8 +192,18 @@ module ClientApiBuilder
181
192
  end
182
193
  expected_response_codes.map!(&:to_s)
183
194
 
195
+ stream_param =
196
+ case options[:stream]
197
+ when true,
198
+ :file
199
+ :file
200
+ when :io
201
+ :io
202
+ end
203
+
184
204
  method_args = named_arguments.map { |arg_name| "#{arg_name}:" }
185
205
  method_args += ['body:'] if has_body_param
206
+ method_args += ["#{stream_param}:"] if stream_param
186
207
  method_args += ['**__options__', '&block']
187
208
 
188
209
  code = "def #{method_name}(" + method_args.join(', ') + ")\n"
@@ -194,9 +215,30 @@ module ClientApiBuilder
194
215
  code += " __body__ = build_body(__body__, __options__)\n"
195
216
  code += " __headers__ = build_headers(__options__)\n"
196
217
  code += " __connection_options__ = build_connection_options(__options__)\n"
197
- code += " @response = request(method: #{http_method.inspect}, uri: __uri__, body: __body__, headers: __headers__, connection_options: __connection_options__)\n"
218
+ code += " @request_options = {method: #{http_method.inspect}, uri: __uri__, body: __body__, headers: __headers__, connection_options: __connection_options__}\n"
219
+ code += " @request_options[:#{stream_param}] = #{stream_param}\n" if stream_param
220
+
221
+ case options[:stream]
222
+ when true,
223
+ :file,
224
+ :io
225
+ code += " @response = stream_to_file(**@request_options)\n"
226
+ when :block
227
+ code += " @response = stream(**@request_options, &block)\n"
228
+ else
229
+ code += " @response = request(**@request_options)\n"
230
+ end
231
+
198
232
  code += " expected_response_code!(@response, __expected_response_codes__, __options__)\n"
199
- code += " handle_response(@response, __options__, &block)\n"
233
+
234
+ if options[:stream] || options[:return] == :response
235
+ code += " @response\n"
236
+ elsif options[:return] == :body
237
+ code += " @response.body\n"
238
+ else
239
+ code += " handle_response(@response, __options__, &block)\n"
240
+ end
241
+
200
242
  code += "end\n"
201
243
  code
202
244
  end
@@ -211,11 +253,23 @@ module ClientApiBuilder
211
253
  end
212
254
 
213
255
  def build_headers(options)
214
- if options[:headers]
215
- self.class.headers.merge(options[:headers])
216
- else
217
- self.class.headers
256
+ headers = {}
257
+
258
+ add_header_proc = proc do |name, value|
259
+ headers[name] =
260
+ if value.is_a?(Proc)
261
+ instance_eval(&value)
262
+ elsif value.is_a?(Symbol)
263
+ send(value)
264
+ else
265
+ value
266
+ end
218
267
  end
268
+
269
+ self.class.headers.each(&add_header_proc)
270
+ options[:headers]&.each(&add_header_proc)
271
+
272
+ headers
219
273
  end
220
274
 
221
275
  def build_connection_options(options)
@@ -227,8 +281,23 @@ module ClientApiBuilder
227
281
  end
228
282
 
229
283
  def build_query(query, options)
230
- query.merge!(options[:query]) if options[:query]
231
- self.class.build_query(query)
284
+ query_params = {}
285
+
286
+ add_query_param_proc = proc do |name, value|
287
+ query_params[name] =
288
+ if value.is_a?(Proc)
289
+ instance_eval(&value)
290
+ elsif value.is_a?(Symbol)
291
+ send(value)
292
+ else
293
+ value
294
+ end
295
+ end
296
+
297
+ self.class.query_params.each(&add_query_param_proc)
298
+ query&.each(&add_query_param_proc)
299
+
300
+ self.class.build_query(query_params)
232
301
  end
233
302
 
234
303
  def build_body(body, options)
@@ -257,7 +326,16 @@ module ClientApiBuilder
257
326
  end
258
327
 
259
328
  def handle_response(response, options, &block)
260
- data = parse_response(response, options)
329
+ data =
330
+ case options[:return]
331
+ when :response
332
+ response
333
+ when :body
334
+ response.body
335
+ else
336
+ parse_response(response, options)
337
+ end
338
+
261
339
  if block
262
340
  instance_exec(data, &block)
263
341
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: client-api-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Doug Youch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-05 00:00:00.000000000 Z
11
+ date: 2021-07-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Utility for constructing API clients
14
14
  email: dougyouch@gmail.com
@@ -24,6 +24,7 @@ files:
24
24
  - LICENSE
25
25
  - README.md
26
26
  - client-api-builder.gemspec
27
+ - examples/basic_auth_example_client.rb
27
28
  - lib/client-api-builder.rb
28
29
  - lib/client_api_builder/net_http_request.rb
29
30
  - lib/client_api_builder/query_params.rb
@@ -48,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
49
  - !ruby/object:Gem::Version
49
50
  version: '0'
50
51
  requirements: []
51
- rubygems_version: 3.1.2
52
+ rubygems_version: 3.2.3
52
53
  signing_key:
53
54
  specification_version: 4
54
55
  summary: Develop Client API libraries faster