my_api_client 0.13.0 → 0.14.0.pre

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: 5e287e051f0699595e499150dd4e4c303e00a82f951ffc86b13afde142a3720e
4
- data.tar.gz: 7725d581e64d01683a636f56e86d217010d536f827023d691faca3b5cbbe2264
3
+ metadata.gz: d52de78feca8df4a1daac75f796382190d0f383c5f0e379111544d18ae863627
4
+ data.tar.gz: 76fd03b48893738aa1a1953592c877eba6dd43a6b9c4066a197453f9425ecfa7
5
5
  SHA512:
6
- metadata.gz: c37ce83c7a27302b8e890087251c67b955e8398b95d08a78b47447401cf0b3332b9bcd66c0e46e4e578a5a51e80f0a4a5fcea576c69fd8d29be8fa5c1c670720
7
- data.tar.gz: 9a42a194c50def52f2aca6f9c54aac80dd7e4191114aa24fef543f81fab235417b3ec1f86ff2f960cd77cd1ff17188df5c073a4574df80fed9963375060058ce
6
+ metadata.gz: 95069064c4d7e6f31abbe302db40d11f574726c11631513d3e40b3fd158e77e95ab81079d0fd4033833aac826722455938fc69605acbee0c2ecb58b11a3c949f
7
+ data.tar.gz: 2c5fceee08ba837afb4901feca3d531e09c8a5d4c2ba6756b2eddd9f185050686e1eed304e077f82aa2f4aa85fe1cb723c17ec7de32470210fc1347cc94ea5fa
@@ -5,7 +5,7 @@
5
5
  version: 2.1
6
6
 
7
7
  orbs:
8
- ruby-orbs: sue445/ruby-orbs@1.4.5
8
+ ruby-orbs: sue445/ruby-orbs@1.6.0
9
9
  code-climate: rvla/code-climate@0.0.2
10
10
 
11
11
  references:
@@ -0,0 +1,16 @@
1
+ version: 1
2
+ update_configs:
3
+ - package_manager: "ruby:bundler"
4
+ directory: "/"
5
+ update_schedule: "daily"
6
+ default_reviewers:
7
+ - "ryz310"
8
+ default_labels:
9
+ - "dependabot"
10
+ automerged_updates:
11
+ - match:
12
+ dependency_type: "development"
13
+ update_type: "all"
14
+ - match:
15
+ dependency_type: "production"
16
+ update_type: "semver:patch"
@@ -7,11 +7,10 @@ inherit_from: .rubocop_todo.yml
7
7
  AllCops:
8
8
  TargetRubyVersion: 2.4
9
9
 
10
- Metrics/AbcSize:
11
- Max: 20
10
+ Layout/LineLength:
11
+ Max: 100
12
12
 
13
13
  Metrics/BlockLength:
14
- Max: 50
15
14
  Exclude:
16
15
  - 'my_api_client.gemspec'
17
16
  - 'lib/my_api_client/rspec/matchers/**/*'
@@ -20,15 +19,10 @@ Metrics/BlockLength:
20
19
  Metrics/MethodLength:
21
20
  Max: 15
22
21
 
23
- Metrics/LineLength:
24
- Max: 100
25
-
26
22
  Naming/AccessorMethodName:
27
- Enabled: false
28
-
29
- Style/ClassAndModuleChildren:
30
23
  Exclude:
31
- - 'spec/**/*'
24
+ - spec/dummy_app/api_clients/example_api_client.rb
25
+ - spec/lib/my_api_client/rspec/matchers/be_handled_as_an_error_spec.rb
32
26
 
33
27
  Style/TrailingCommaInArrayLiteral:
34
28
  EnforcedStyleForMultiline: comma
@@ -1,17 +1,7 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2020-01-08 23:41:00 +0000 using RuboCop version 0.79.0.
3
+ # on 2020-02-21 23:30:47 +0000 using RuboCop version 0.80.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 18
10
- RSpec/LeakyConstantDeclaration:
11
- Exclude:
12
- - 'spec/lib/my_api_client/base_spec.rb'
13
- - 'spec/lib/my_api_client/config_spec.rb'
14
- - 'spec/lib/my_api_client/error_handling_spec.rb'
15
- - 'spec/lib/my_api_client/exceptions_spec.rb'
16
- - 'spec/lib/my_api_client/request_spec.rb'
17
- - 'spec/lib/my_api_client/rspec/stub_spec.rb'
@@ -1,5 +1,83 @@
1
1
  # Change log
2
2
 
3
+ ## v0.14.0.pre (Feb 23, 2020)
4
+
5
+ ### Refactoring
6
+
7
+ * [#179](https://github.com/ryz310/my_api_client/pull/179) Change the "with" option structure ([@ryz310](https://github.com/ryz310))
8
+ * [#206](https://github.com/ryz310/my_api_client/pull/206) Rebuild api request processing ([@ryz310](https://github.com/ryz310))
9
+ * [#207](https://github.com/ryz310/my_api_client/pull/207) Fix offending codes ([@ryz310](https://github.com/ryz310))
10
+
11
+ ### Breaking Change
12
+
13
+ * [#196](https://github.com/ryz310/my_api_client/pull/196) Change the request structure ([@ryz310](https://github.com/ryz310))
14
+
15
+ > ### logging
16
+ >
17
+ > **before**
18
+ >
19
+ > ```
20
+ > I, [2020-02-02T15:26:53.788092 #93220] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts`: "Start"
21
+ > I, [2020-02-02T15:26:55.760452 #93220] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts`: "Duration 1.97186 sec"
22
+ > I, [2020-02-02T15:26:55.760739 #93220] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts`: "Success (200)"
23
+ > ```
24
+ >
25
+ > **after**
26
+ >
27
+ > Shows URL with query strings.
28
+ >
29
+ > ```
30
+ > I, [2020-02-02T15:20:47.471040 #90870] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts?page=1&per_page=100&q=user%3Aryosuke_sato+category%3Aunsorted`: "Start"
31
+ > I, [2020-02-02T15:20:49.516099 #90870] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts?page=1&per_page=100&q=user%3Aryosuke_sato+category%3Aunsorted`: "Duration 2.034907 sec"
32
+ > I, [2020-02-02T15:20:49.516391 #90870] INFO -- : API request `GET https://api.esa.io/v1/teams/feedforce/posts?page=1&per_page=100&q=user%3Aryosuke_sato+category%3Aunsorted`: "Success (200)"
33
+ > ```
34
+ >
35
+ > ### MyApiClient::Params::Request
36
+ >
37
+ > **before**
38
+ >
39
+ > ```rb
40
+ > request_params.metadata # =>
41
+ > # {
42
+ > # line: 'GET path/to/resource',
43
+ > # headers: { 'Content-Type': 'application/json; charset=utf-8' },
44
+ > # query: { key: 'value' }
45
+ > # }
46
+ > ```
47
+ >
48
+ > **after**
49
+ >
50
+ > The `#metadata` does not include `query` key and then includes full URL into `line` value.
51
+ >
52
+ > ```rb
53
+ > request_params.metadata # =>
54
+ > # {
55
+ > # line: 'GET https://example.com/path/to/resource?key=value',
56
+ > # headers: { 'Content-Type': 'application/json; charset=utf-8' }
57
+ > # }
58
+ > ```
59
+
60
+ ### Rubocop Challenge
61
+
62
+ * [#205](https://github.com/ryz310/my_api_client/pull/205) Re-generate .rubocop_todo.yml with RuboCop v0.80.0 ([@ryz310](https://github.com/ryz310))
63
+
64
+ ### Dependabot
65
+
66
+ * [#190](https://github.com/ryz310/my_api_client/pull/190) Add a config file of the dependabot ([@ryz310](https://github.com/ryz310))
67
+ * [#183](https://github.com/ryz310/my_api_client/pull/183) Bump pry-byebug from 3.7.0 to 3.8.0 ([@ryz310](https://github.com/ryz310))
68
+ * [#194](https://github.com/ryz310/my_api_client/pull/194) Bump bugsnag from 6.12.2 to 6.13.0 ([@ryz310](https://github.com/ryz310))
69
+ * [#197](https://github.com/ryz310/my_api_client/pull/197) Bump webmock from 3.8.0 to 3.8.1 ([@ryz310](https://github.com/ryz310))
70
+ * [#199](https://github.com/ryz310/my_api_client/pull/199) Bump webmock from 3.8.1 to 3.8.2 ([@ryz310](https://github.com/ryz310))
71
+
72
+ ### Renovate
73
+
74
+ * [#193](https://github.com/ryz310/my_api_client/pull/193) Change renovate automerge setting ([@ryz310](https://github.com/ryz310))
75
+ * [#189](https://github.com/ryz310/my_api_client/pull/189) Update the renovate settings ([@ryz310](https://github.com/ryz310))
76
+ * [#184](https://github.com/ryz310/my_api_client/pull/184) Update ruby-orbs orb to v1.5.1 ([@ryz310](https://github.com/ryz310))
77
+ * [#185](https://github.com/ryz310/my_api_client/pull/185) Update ruby-orbs orb to v1.5.4 ([@ryz310](https://github.com/ryz310))
78
+ * [#187](https://github.com/ryz310/my_api_client/pull/187) Update ruby-orbs orb to v1.5.6 ([@ryz310](https://github.com/ryz310))
79
+ * [#192](https://github.com/ryz310/my_api_client/pull/192) Update ruby-orbs orb to v1.6.0 ([@ryz310](https://github.com/ryz310))
80
+
3
81
  ## v0.13.0 (Jan 21, 2020)
4
82
 
5
83
  ### Feature
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- my_api_client (0.13.0)
4
+ my_api_client (0.14.0.pre)
5
5
  activesupport (>= 4.2.0)
6
6
  faraday (>= 0.17.1)
7
7
  jsonpath
@@ -18,11 +18,11 @@ GEM
18
18
  addressable (2.7.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
20
  ast (2.4.0)
21
- bugsnag (6.12.2)
21
+ bugsnag (6.13.0)
22
22
  concurrent-ruby (~> 1.0)
23
- byebug (11.1.0)
23
+ byebug (11.1.1)
24
24
  coderay (1.1.2)
25
- concurrent-ruby (1.1.5)
25
+ concurrent-ruby (1.1.6)
26
26
  crack (0.4.3)
27
27
  safe_yaml (~> 1.0.0)
28
28
  diff-lcs (1.3)
@@ -47,12 +47,13 @@ GEM
47
47
  pry (0.12.2)
48
48
  coderay (~> 1.1.0)
49
49
  method_source (~> 0.9.0)
50
- pry-byebug (3.7.0)
50
+ pry-byebug (3.8.0)
51
51
  byebug (~> 11.0)
52
52
  pry (~> 0.10)
53
53
  public_suffix (4.0.3)
54
54
  rainbow (3.0.0)
55
55
  rake (13.0.1)
56
+ rexml (3.2.4)
56
57
  rspec (3.9.0)
57
58
  rspec-core (~> 3.9.0)
58
59
  rspec-expectations (~> 3.9.0)
@@ -68,16 +69,17 @@ GEM
68
69
  rspec-support (3.9.2)
69
70
  rspec_junit_formatter (0.4.1)
70
71
  rspec-core (>= 2, < 4, != 2.12.0)
71
- rubocop (0.79.0)
72
+ rubocop (0.80.0)
72
73
  jaro_winkler (~> 1.5.1)
73
74
  parallel (~> 1.10)
74
75
  parser (>= 2.7.0.1)
75
76
  rainbow (>= 2.2.2, < 4.0)
77
+ rexml
76
78
  ruby-progressbar (~> 1.7)
77
79
  unicode-display_width (>= 1.4.0, < 1.7)
78
80
  rubocop-performance (1.5.2)
79
81
  rubocop (>= 0.71.0)
80
- rubocop-rspec (1.37.1)
82
+ rubocop-rspec (1.38.1)
81
83
  rubocop (>= 0.68.1)
82
84
  ruby-progressbar (1.10.1)
83
85
  safe_yaml (1.0.5)
@@ -94,7 +96,7 @@ GEM
94
96
  tzinfo (1.2.6)
95
97
  thread_safe (~> 0.1)
96
98
  unicode-display_width (1.6.1)
97
- webmock (3.8.0)
99
+ webmock (3.8.2)
98
100
  addressable (>= 2.3.6)
99
101
  crack (>= 0.3.2)
100
102
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -115,7 +117,7 @@ DEPENDENCIES
115
117
  rubocop
116
118
  rubocop-performance
117
119
  rubocop-rspec
118
- simplecov
120
+ simplecov (= 0.17.1)
119
121
  webmock
120
122
  yard
121
123
 
@@ -105,7 +105,7 @@ class ExampleApiClient < MyApiClient::Base
105
105
  private
106
106
 
107
107
  # @param params [MyApiClient::Params::Params] HTTP req and res params
108
- # @param logger [MyApiClient::Logger] Logger for a request processing
108
+ # @param logger [MyApiClient::Request::Logger] Logger for a request processing
109
109
  def my_error_handling(params, logger)
110
110
  logger.warn "Response Body: #{params.response.body.inspect}"
111
111
  raise MyApiClient::ClientError, params
@@ -163,7 +163,7 @@ error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
163
163
 
164
164
  ```ruby
165
165
  # @param params [MyApiClient::Params::Params] HTTP req and res params
166
- # @param logger [MyApiClient::Logger] Logger for a request processing
166
+ # @param logger [MyApiClient::Request::Logger] Logger for a request processing
167
167
  def my_error_handling(params, logger)
168
168
  logger.warn "Response Body: #{params.response.body.inspect}"
169
169
  raise MyApiClient::ClientError, params
@@ -11,10 +11,11 @@ require 'my_api_client/service_abstract'
11
11
  require 'my_api_client/version'
12
12
  require 'my_api_client/config'
13
13
  require 'my_api_client/error_handling/generator'
14
- require 'my_api_client/error_handling/process_retry_option'
14
+ require 'my_api_client/error_handling/retry_option_processor'
15
15
  require 'my_api_client/error_handling'
16
16
  require 'my_api_client/exceptions'
17
- require 'my_api_client/logger'
17
+ require 'my_api_client/request/logger'
18
+ require 'my_api_client/request/executor'
18
19
  require 'my_api_client/errors'
19
20
  require 'my_api_client/params/params'
20
21
  require 'my_api_client/params/request'
@@ -21,23 +21,5 @@ module MyApiClient
21
21
  # NOTE: This class **MUST NOT** implement #initialize method. Because it
22
22
  # will become constraint that need call #super in the #initialize at
23
23
  # definition of the child classes.
24
-
25
- HTTP_METHODS = %i[get post patch delete].freeze
26
-
27
- HTTP_METHODS.each do |http_method|
28
- class_eval <<~METHOD, __FILE__, __LINE__ + 1
29
- # Description of ##{http_method}
30
- #
31
- # @param pathname [String]
32
- # @param headers [Hash, nil]
33
- # @param query [Hash, nil]
34
- # @param body [Hash, nil]
35
- # @return [Sawyer::Resouce] description_of_returned_object
36
- def #{http_method}(pathname, headers: nil, query: nil, body: nil)
37
- _request :#{http_method}, pathname, headers, query, body, logger
38
- end
39
- METHOD
40
- end
41
- alias put patch
42
24
  end
43
25
  end
@@ -16,34 +16,5 @@ module MyApiClient
16
16
  METHOD
17
17
  end
18
18
  end
19
-
20
- # Extracts schema and hostname from endpoint
21
- #
22
- # @example Extracts schema and hostname from 'https://example.com/path/to/api'
23
- # schema_and_hostname # => 'https://example.com'
24
- # @return [String] description_of_returned_object
25
- def schema_and_hostname
26
- if _uri.default_port == _uri.port
27
- "#{_uri.scheme}://#{_uri.host}"
28
- else
29
- "#{_uri.scheme}://#{_uri.host}:#{_uri.port}"
30
- end
31
- end
32
-
33
- # Extracts pathname from endpoint
34
- #
35
- # @example Extracts pathname from 'https://example.com/path/to/api'
36
- # common_path # => 'path/to/api'
37
- # @return [String] The pathanem
38
- def common_path
39
- _uri.path
40
- end
41
-
42
- private
43
-
44
- # @return [URI] Returns a memoized URI instance
45
- def _uri
46
- @_uri ||= URI.parse(endpoint)
47
- end
48
19
  end
49
20
  end
@@ -40,30 +40,20 @@ module MyApiClient
40
40
  # @option retry [TrueClass, Hash]
41
41
  # If the error detected, retries the API request. Requires `raise` option.
42
42
  # You can set `true` or `retry_on` options (`wait` and `attempts`).
43
- # @yield [MyApiClient::Params::Params, MyApiClient::Logger]
43
+ # @yield [MyApiClient::Params::Params, MyApiClient::Request::Logger]
44
44
  # Executes the block when error detected.
45
45
  # Forbid to be used with the` retry` option.
46
46
  def error_handling(**options, &block)
47
47
  options[:block] = block
48
- retry_options = ProcessRetryOption.call(error_handling_options: options)
48
+ retry_options = RetryOptionProcessor.call(error_handling_options: options)
49
49
  retry_on(options[:raise], **retry_options) if retry_options
50
50
 
51
- temp = error_handlers.dup
52
- temp << ->(response) { Generator.call(**options.merge(response: response)) }
53
- self.error_handlers = temp
51
+ new_error_handlers = error_handlers.dup
52
+ new_error_handlers << lambda { |instance, response|
53
+ Generator.call(**options.merge(instance: instance, response: response))
54
+ }
55
+ self.error_handlers = new_error_handlers
54
56
  end
55
57
  end
56
-
57
- # The error handlers defined later takes precedence
58
- #
59
- # @param response [Sawyer::Response] describe_params_here
60
- # @return [Proc, Symbol, nil] description_of_returned_object
61
- def error_handling(response)
62
- error_handlers.reverse_each do |error_handler|
63
- result = error_handler.call(response)
64
- return result unless result.nil?
65
- end
66
- nil
67
- end
68
58
  end
69
59
  end
@@ -4,10 +4,12 @@ module MyApiClient
4
4
  module ErrorHandling
5
5
  # Generates an error handler proc (or symbol)
6
6
  class Generator < ServiceAbstract
7
- ARGUMENTS = %i[response status_code json with raise block].freeze
7
+ ARGUMENTS = %i[instance response status_code json with raise block].freeze
8
8
 
9
9
  # @param options [Hash]
10
10
  # Options for this generator
11
+ # @option instance [MyApiClient::Base]
12
+ # The API client class.
11
13
  # @option response [Sawyer::Response]
12
14
  # The target of verifying
13
15
  # @option status_code [String, Range, Integer, Regexp]
@@ -22,9 +24,7 @@ module MyApiClient
22
24
  # @option block [Proc]
23
25
  # Executes the block when error detected
24
26
  # @return [Proc]
25
- # Returns value as `Proc` if given `raise` or `block` option
26
- # @return [Symbol]
27
- # Returns value as `Symbol` if given `with` option
27
+ # Returns value as `Proc`.
28
28
  def initialize(**options)
29
29
  options[:raise] ||= MyApiClient::Error
30
30
  verify_and_set_arguments(**options)
@@ -38,10 +38,14 @@ module MyApiClient
38
38
  return unless match?(_status_code, _response.status)
39
39
  return unless match_all?(_json, _response.body)
40
40
 
41
+ generate_error_handler
42
+ end
43
+
44
+ def generate_error_handler
41
45
  if _block
42
46
  ->(params, logger) { _block.call(params, logger) }
43
47
  elsif _with
44
- _with
48
+ ->(params, logger) { _instance.send(_with, params, logger) }
45
49
  else
46
50
  ->(params, _) { raise _raise, params }
47
51
  end
@@ -3,7 +3,7 @@
3
3
  module MyApiClient
4
4
  module ErrorHandling
5
5
  # Processes the `retry` option.
6
- class ProcessRetryOption < ServiceAbstract
6
+ class RetryOptionProcessor < ServiceAbstract
7
7
  # @param error_handling_options [Hash]
8
8
  # Options for the retry.
9
9
  # @option raise [MyApiClient::Error]
@@ -4,20 +4,18 @@ module MyApiClient
4
4
  module Params
5
5
  # Description of Params
6
6
  class Request
7
- attr_reader :method, :pathname, :headers, :query, :body
7
+ attr_reader :method, :uri, :headers, :body
8
8
 
9
9
  # Description of #initialize
10
10
  #
11
11
  # @param method [Symbol] describe_method_here
12
- # @param pathname [String] describe_pathname_here
12
+ # @param uri [URI] describe_uri_here
13
13
  # @param headers [Hash, nil] describe_headers_here
14
- # @param query [Hash, nil] describe_query_here
15
14
  # @param body [Hash, nil] describe_body_here
16
- def initialize(method, pathname, headers, query, body)
15
+ def initialize(method, uri, headers, body)
17
16
  @method = method
18
- @pathname = pathname
17
+ @uri = uri
19
18
  @headers = headers
20
- @query = query
21
19
  @body = body
22
20
  end
23
21
 
@@ -25,7 +23,7 @@ module MyApiClient
25
23
  #
26
24
  # @return [Array<Object>] Arguments for Sawyer::Agent#call
27
25
  def to_sawyer_args
28
- [method, pathname, body, { headers: headers, query: query }]
26
+ [method, uri.to_s, body, { headers: headers }]
29
27
  end
30
28
 
31
29
  # Generate metadata for bugsnag.
@@ -34,9 +32,8 @@ module MyApiClient
34
32
  # @return [Hash] Metadata for bugsnag
35
33
  def metadata
36
34
  {
37
- line: "#{method.upcase} #{pathname}",
35
+ line: "#{method.upcase} #{uri}",
38
36
  headers: headers,
39
- query: query,
40
37
  body: body,
41
38
  }.compact
42
39
  end
@@ -46,7 +43,7 @@ module MyApiClient
46
43
  #
47
44
  # @return [String] Contents as string
48
45
  def inspect
49
- { method: method, pathname: pathname, headers: headers, query: query, body: body }.inspect
46
+ { method: method, uri: uri.to_s, headers: headers, body: body }.inspect
50
47
  end
51
48
  end
52
49
  end
@@ -3,85 +3,68 @@
3
3
  module MyApiClient
4
4
  # Description of Request
5
5
  module Request
6
- # Description of #_request
7
- #
8
- # @param http_method [Symbol] describe_http_method_here
9
- # @param pathname [String] describe_pathname_here
10
- # @param headers [Hash, nil] describe_headers_here
11
- # @param query [Hash, nil] describe_query_here
12
- # @param body [Hash, nil] describe_body_here
13
- # @param logger [::Logger] describe_logger_here
14
- # @return [Sawyer::Resource] description_of_returned_object
15
- # rubocop:disable Metrics/ParameterLists
16
- def _request(http_method, pathname, headers, query, body, logger)
17
- processed_path = [common_path, pathname].join('/').gsub('//', '/')
18
- request_params = Params::Request.new(http_method, processed_path, headers, query, body)
19
- agent # Initializes for faraday
20
- request_logger = Logger.new(logger, faraday, http_method, processed_path)
21
- call(:_execute, request_params, request_logger)
22
- end
23
- # rubocop:enable Metrics/ParameterLists
24
-
25
- private
6
+ HTTP_METHODS = %i[get post patch delete].freeze
26
7
 
27
- # Description of #agent
28
- #
29
- # @return [Sawyer::Agent] description_of_returned_object
30
- def agent
31
- @agent ||= Sawyer::Agent.new(schema_and_hostname, faraday: faraday)
8
+ HTTP_METHODS.each do |http_method|
9
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
10
+ # Executes HTTP request with #{http_method.upcase} method
11
+ #
12
+ # @param pathname [String]
13
+ # Pathname of the request target URL.
14
+ # It's joined with the defined `endpoint`.
15
+ # @param headers [Hash, nil]
16
+ # Request headers.
17
+ # @param query [Hash, nil]
18
+ # Query string.
19
+ # @param body [Hash, nil]
20
+ # Request body. You should not specify it when use GET method.
21
+ # @return [Sawyer::Resouce]
22
+ # Response body instance.
23
+ def #{http_method}(pathname, headers: nil, query: nil, body: nil)
24
+ query_strings = query.present? ? '?' + query&.to_query : ''
25
+ uri = URI.join(File.join(endpoint, pathname), query_strings)
26
+ response = call(:_request, :#{http_method}, uri, headers, body)
27
+ response.data
28
+ end
29
+ METHOD
32
30
  end
31
+ alias put patch
33
32
 
34
- # Description of #faraday
35
- #
36
- # @return [Faraday::Connection] description_of_returned_object
37
- def faraday
38
- @faraday ||=
39
- Faraday.new(
40
- nil,
41
- request: {
42
- timeout: (http_read_timeout if respond_to?(:http_read_timeout)),
43
- open_timeout: (http_open_timeout if respond_to?(:http_open_timeout)),
44
- }.compact
45
- )
46
- end
33
+ private
47
34
 
48
- # Description of #_execute
35
+ # Executes HTTP request.
49
36
  #
50
- # @param request_params [MyApiClient::Params::Request] describe_request_params_here
51
- # @param request_logger [MyApiClient::Logger] describe_request_logger_here
52
- # @return [Sawyer::Resource] description_of_returned_object
53
- # @raise [MyApiClient::Error]
54
- def _execute(request_params, request_logger)
55
- request_logger.info('Start')
56
- response = agent.call(*request_params.to_sawyer_args)
57
- request_logger.info("Duration #{response.timing} sec")
58
- params = Params::Params.new(request_params, response)
59
- _verify(params, request_logger)
60
- rescue *NETWORK_ERRORS => e
61
- params ||= Params::Params.new(request_params, nil)
62
- request_logger.error("Network Error (#{e.message})")
63
- raise MyApiClient::NetworkError.new(params, e)
64
- rescue MyApiClient::Error => e
65
- request_logger.warn("Failure (#{response.status})")
66
- raise e
67
- else
68
- request_logger.info("Success (#{response.status})")
69
- response.data
37
+ # @param http_method [Symbol]
38
+ # HTTP method. e.g. `:get`, `:post`, `:patch` and `:delete`.
39
+ # @param uri [URI]
40
+ # Request target URI including query strings.
41
+ # @param headers [Hash, nil]
42
+ # Request headers.
43
+ # @param body [Hash, nil]
44
+ # Request body.
45
+ # @return [Sawyer::Response]
46
+ # Response instance.
47
+ def _request(http_method, uri, headers, body)
48
+ request_params = Params::Request.new(http_method, uri, headers, body)
49
+ request_logger = Logger.new(logger, http_method, uri)
50
+ Executor.call(
51
+ instance: self,
52
+ request_params: request_params,
53
+ request_logger: request_logger,
54
+ faraday_options: faraday_options
55
+ )
70
56
  end
71
57
 
72
- # Description of #_verify
58
+ # Generates options for the faraday instance.
73
59
  #
74
- # @param params [MyApiClient::Params::Params] describe_params_here
75
- # @param request_logger [MyApiClient::Logger] describe_request_logger_here
76
- # @return [nil] description_of_returned_object
77
- # @raise [MyApiClient::Error]
78
- def _verify(params, request_logger)
79
- case error_handler = error_handling(params.response)
80
- when Proc
81
- error_handler.call(params, request_logger)
82
- when Symbol
83
- send(error_handler, params, request_logger)
84
- end
60
+ # @return [Hash] Generated options.
61
+ def faraday_options
62
+ {
63
+ request: {
64
+ timeout: (http_read_timeout if respond_to?(:http_read_timeout)),
65
+ open_timeout: (http_open_timeout if respond_to?(:http_open_timeout)),
66
+ }.compact,
67
+ }
85
68
  end
86
69
  end
87
70
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MyApiClient
4
+ module Request
5
+ # Executes HTTP request with specified parameters.
6
+ class Executor < ServiceAbstract
7
+ # @param instance [MyApiClient::Base]
8
+ # The my_api_client instance.
9
+ # The instance method will be called on error handling.
10
+ # @param request_params [MyApiClient::Params::Request]
11
+ # Request parameter instance.
12
+ # @param request_logger [MyApiClient::Logger]
13
+ # Request logger instance.
14
+ # @param faraday_options [Hash]
15
+ # Options for the faraday instance. Mainly used for timeout settings.
16
+ # @return [Sawyer::Response]
17
+ # Response instance.
18
+ # @raise [MyApiClient::Error]
19
+ # Raises on invalid response or network errors.
20
+ def initialize(instance:, request_params:, request_logger:, faraday_options:)
21
+ @instance = instance
22
+ @request_params = request_params
23
+ @request_logger = request_logger
24
+ faraday = Faraday.new(nil, faraday_options)
25
+ @agent = Sawyer::Agent.new('', faraday: faraday)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :instance, :request_params, :request_logger, :agent
31
+
32
+ def call
33
+ request_logger.info('Start')
34
+ response = api_request
35
+ request_logger.info("Duration #{response.timing} sec")
36
+ verify(response)
37
+ rescue MyApiClient::Error => e
38
+ request_logger.warn("Failure (#{e.message})")
39
+ raise
40
+ else
41
+ request_logger.info("Success (#{response.status})")
42
+ response
43
+ end
44
+
45
+ # Executes HTTP request to the API.
46
+ #
47
+ # @return [Sawyer::Response]
48
+ # Response instance.
49
+ # @raise [MyApiClient::NetworkError]
50
+ # Raises on any network errors.
51
+ def api_request
52
+ agent.call(*request_params.to_sawyer_args)
53
+ rescue *NETWORK_ERRORS => e
54
+ params = Params::Params.new(request_params, nil)
55
+ raise MyApiClient::NetworkError.new(params, e)
56
+ end
57
+
58
+ # Verifies the response.
59
+ #
60
+ # @param response_params [Sawyer::Response]
61
+ # The target response.
62
+ # @return [nil]
63
+ # Returns nil when a valid response.
64
+ # @raise [MyApiClient::Error]
65
+ # Raises on any invalid response.
66
+ def verify(response_params)
67
+ params = Params::Params.new(request_params, response_params)
68
+ find_error_handler(response_params)&.call(params, request_logger)
69
+ end
70
+
71
+ # Executes response verifyment. If an invalid response is detected, return
72
+ # the error handler procedure. The error handlers defined later takes precedence.
73
+ #
74
+ # @param response_params [Sawyer::Response]
75
+ # The target response.
76
+ # @return [nil]
77
+ # Returns nil when a valid response.
78
+ # @return [Proc]
79
+ # Returns Proc when a invalid response.
80
+ def find_error_handler(response_params)
81
+ instance.error_handlers.reverse_each do |error_handler|
82
+ result = error_handler.call(instance, response_params)
83
+ return result unless result.nil?
84
+ end
85
+ nil
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MyApiClient
4
+ module Request
5
+ # Description of Logger
6
+ class Logger
7
+ attr_reader :logger, :method, :uri
8
+
9
+ LOG_LEVEL = %i[debug info warn error fatal].freeze
10
+
11
+ # Description of #initialize
12
+ #
13
+ # @param logger [::Logger] describe_logger_here
14
+ # @param method [String] HTTP method
15
+ # @param uri [URI] Target URI
16
+ def initialize(logger, method, uri)
17
+ @logger = logger
18
+ @method = method.to_s.upcase
19
+ @uri = uri
20
+ end
21
+
22
+ LOG_LEVEL.each do |level|
23
+ class_eval <<~METHOD, __FILE__, __LINE__ + 1
24
+ def #{level}(message)
25
+ logger.#{level}(format(message))
26
+ end
27
+ METHOD
28
+ end
29
+
30
+ private
31
+
32
+ def format(message)
33
+ "API request `#{method} #{uri}`: \"#{message}\""
34
+ end
35
+ end
36
+ end
37
+ end
@@ -4,8 +4,8 @@ module MyApiClient
4
4
  # Helper module for rspec custom matcher
5
5
  module MatcherHelper
6
6
  def disable_logging
7
- logger = instance_double(MyApiClient::Logger, info: nil, warn: nil)
8
- allow(MyApiClient::Logger).to receive(:new).and_return(logger)
7
+ logger = instance_double(MyApiClient::Request::Logger, info: nil, warn: nil)
8
+ allow(MyApiClient::Request::Logger).to receive(:new).and_return(logger)
9
9
  end
10
10
 
11
11
  def dummy_response(status: 200, headers: {}, body: nil)
@@ -45,6 +45,7 @@ RSpec::Matchers.define :be_handled_as_an_error do |expected_error_class|
45
45
 
46
46
  attr_reader :sawyer
47
47
 
48
+ # rubocop:disable Metrics/AbcSize
48
49
  def init
49
50
  disable_logging
50
51
  response = dummy_response(
@@ -56,6 +57,7 @@ RSpec::Matchers.define :be_handled_as_an_error do |expected_error_class|
56
57
  allow(Sawyer::Agent).to receive(:new).and_return(sawyer)
57
58
  allow(MyApiClient::Sleeper).to receive(:call)
58
59
  end
60
+ # rubocop:enable Metrics/AbcSize
59
61
 
60
62
  def set_validation_for_retry_count
61
63
  return if retry_count.nil?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MyApiClient
4
- VERSION = '0.13.0'
4
+ VERSION = '0.14.0.pre'
5
5
  end
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency 'rubocop'
38
38
  spec.add_development_dependency 'rubocop-performance'
39
39
  spec.add_development_dependency 'rubocop-rspec'
40
- spec.add_development_dependency 'simplecov'
40
+ spec.add_development_dependency 'simplecov', '0.17.1'
41
41
  spec.add_development_dependency 'webmock'
42
42
  spec.add_development_dependency 'yard'
43
43
  end
@@ -1,5 +1,21 @@
1
1
  {
2
2
  "extends": [
3
3
  "config:base"
4
+ ],
5
+ "packageRules": [
6
+ {
7
+ "updateTypes": ["major"],
8
+ "labels": ["renovate", "major"]
9
+ },
10
+ {
11
+ "updateTypes": ["minor"],
12
+ "labels": ["renovate", "minor", "auto merge"],
13
+ "automerge": true
14
+ },
15
+ {
16
+ "updateTypes": ["patch"],
17
+ "labels": ["renovate", "patch", "auto merge"],
18
+ "automerge": true
19
+ }
4
20
  ]
5
21
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: my_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - ryz310
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-21 00:00:00.000000000 Z
11
+ date: 2020-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -182,16 +182,16 @@ dependencies:
182
182
  name: simplecov
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - ">="
185
+ - - '='
186
186
  - !ruby/object:Gem::Version
187
- version: '0'
187
+ version: 0.17.1
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - ">="
192
+ - - '='
193
193
  - !ruby/object:Gem::Version
194
- version: '0'
194
+ version: 0.17.1
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: webmock
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -228,6 +228,7 @@ extensions: []
228
228
  extra_rdoc_files: []
229
229
  files:
230
230
  - ".circleci/config.yml"
231
+ - ".dependabot/config.yml"
231
232
  - ".envrc.skeleton"
232
233
  - ".gem_comet.yml"
233
234
  - ".gitignore"
@@ -262,14 +263,15 @@ files:
262
263
  - lib/my_api_client/config.rb
263
264
  - lib/my_api_client/error_handling.rb
264
265
  - lib/my_api_client/error_handling/generator.rb
265
- - lib/my_api_client/error_handling/process_retry_option.rb
266
+ - lib/my_api_client/error_handling/retry_option_processor.rb
266
267
  - lib/my_api_client/errors.rb
267
268
  - lib/my_api_client/exceptions.rb
268
269
  - lib/my_api_client/integrations/bugsnag.rb
269
- - lib/my_api_client/logger.rb
270
270
  - lib/my_api_client/params/params.rb
271
271
  - lib/my_api_client/params/request.rb
272
272
  - lib/my_api_client/request.rb
273
+ - lib/my_api_client/request/executor.rb
274
+ - lib/my_api_client/request/logger.rb
273
275
  - lib/my_api_client/rspec.rb
274
276
  - lib/my_api_client/rspec/matcher_helper.rb
275
277
  - lib/my_api_client/rspec/matchers/be_handled_as_an_error.rb
@@ -295,9 +297,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
295
297
  version: 2.4.0
296
298
  required_rubygems_version: !ruby/object:Gem::Requirement
297
299
  requirements:
298
- - - ">="
300
+ - - ">"
299
301
  - !ruby/object:Gem::Version
300
- version: '0'
302
+ version: 1.3.1
301
303
  requirements: []
302
304
  rubygems_version: 3.1.2
303
305
  signing_key:
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MyApiClient
4
- # Description of Logger
5
- class Logger
6
- attr_reader :logger, :method, :pathname
7
-
8
- LOG_LEVEL = %i[debug info warn error fatal].freeze
9
-
10
- # Description of #initialize
11
- #
12
- # @param logger [::Logger] describe_logger_here
13
- # @param faraday [Faraday::Connection] describe_faraday_here
14
- # @param method [String] HTTP method
15
- # @param pathname [String] The path name
16
- def initialize(logger, faraday, method, pathname)
17
- @logger = logger
18
- @method = method.to_s.upcase
19
- @pathname = faraday.build_exclusive_url(pathname)
20
- end
21
-
22
- LOG_LEVEL.each do |level|
23
- class_eval <<~METHOD, __FILE__, __LINE__ + 1
24
- def #{level}(message)
25
- logger.#{level}(format(message))
26
- end
27
- METHOD
28
- end
29
-
30
- private
31
-
32
- def format(message)
33
- "API request `#{method} #{pathname}`: \"#{message}\""
34
- end
35
- end
36
- end