nxt_http_client 0.2.9 → 0.3.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: d0f3125c7163d56e5656ded82aeb30d4d52982f6a4f7cccfdc0fab3c43114af3
4
- data.tar.gz: 4a818011bbf91ad2a9240b8f16bf0224c6b009b8147e5430972762ac0a9bd964
3
+ metadata.gz: 22aa2f16ec7170133779ae75097fdd0c164a3a3a793a98f8d565d6ddfd2ca96c
4
+ data.tar.gz: c21b929937fe483cd7d56754d50ba37ae9d83b10bb120e5b772b425f3a04e559
5
5
  SHA512:
6
- metadata.gz: 145ccc07ab888597f7dca77c568cab3117580d97bd47bd343119a0b89d302e5c8263fe4513544595f48cf0944648d7dc2a8e51933cb62a8a720c2c0569d03210
7
- data.tar.gz: 030f4cdd69ed052bcafe85e246ac580a1468c96d6f6c70c567c4d918aa0a36048316ccb9ebf04f95d06ecea74ea9279a04506da4bd1b4992c35b47366f9bada5
6
+ metadata.gz: be208ed0c5e3b617d48dcca068c8c588e9748ab34f23a538d9039f6b7ed1649dd96f54ec0dbb716de3c823b5f6ff452b06eadfd79a85514f97106d4fef0d7fd4
7
+ data.tar.gz: 0743b9d3371ff51381c8a0f5b45547bc86302f0282e8064fe7a93f268e195361ca055ed7a085df38b82653909542488cd6de02a2d5b95abcf547068215097278
@@ -0,0 +1,57 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ - image: circleci/ruby:2.7.0-node
10
+ - image: circleci/redis:5.0.4
11
+ environment:
12
+ BUNDLER_VERSION: 2.1.4
13
+
14
+ working_directory: ~/repo
15
+
16
+ steps:
17
+ - checkout
18
+
19
+ # Download and cache dependencies
20
+ - restore_cache:
21
+ keys:
22
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
23
+
24
+ - run: gem install bundler --version $BUNDLER_VERSION
25
+
26
+ - run:
27
+ name: install dependencies
28
+ command: |
29
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
30
+
31
+ - save_cache:
32
+ paths:
33
+ - ./vendor/bundle
34
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
35
+
36
+ # run tests!
37
+ - run:
38
+ name: run tests
39
+ command: |
40
+ mkdir /tmp/test-results
41
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
42
+ circleci tests split --split-by=timings)"
43
+
44
+ bundle exec rspec \
45
+ --format progress \
46
+ --format RspecJunitFormatter \
47
+ --out /tmp/test-results/rspec.xml \
48
+ --format progress \
49
+ $TEST_FILES
50
+
51
+ # collect reports
52
+ - store_artifacts:
53
+ path: /tmp/rspec/
54
+ destination: rspec
55
+
56
+ - store_test_results:
57
+ path: /tmp/rspec/
@@ -0,0 +1,8 @@
1
+ # v0.2.10 2020-03-10
2
+
3
+ ### Refactored
4
+
5
+ - [internal] Added CHANGELOG.MD
6
+ - Refactored a bit
7
+
8
+ [Compare v0.2.9...v0.2.10](https://github.com/nxt-insurance/nxt_http_client/compare/v0.2.9...v0.2.10)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nxt_http_client (0.2.9)
4
+ nxt_http_client (0.3.0)
5
5
  activesupport (~> 6.0.0)
6
6
  nxt_registry
7
7
  typhoeus
@@ -9,38 +9,38 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (6.0.2.1)
12
+ activesupport (6.0.3.2)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 0.7, < 2)
15
15
  minitest (~> 5.1)
16
16
  tzinfo (~> 1.1)
17
- zeitwerk (~> 2.2)
17
+ zeitwerk (~> 2.2, >= 2.2.2)
18
18
  addressable (2.7.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
20
  coderay (1.1.2)
21
- concurrent-ruby (1.1.5)
21
+ concurrent-ruby (1.1.6)
22
22
  crack (0.4.3)
23
23
  safe_yaml (~> 1.0.0)
24
24
  diff-lcs (1.3)
25
25
  ethon (0.12.0)
26
26
  ffi (>= 1.3.0)
27
- ffi (1.12.1)
28
- hashdiff (1.0.0)
29
- i18n (1.8.2)
27
+ ffi (1.12.2)
28
+ hashdiff (1.0.1)
29
+ i18n (1.8.5)
30
30
  concurrent-ruby (~> 1.0)
31
- method_source (0.9.2)
32
- minitest (5.14.0)
33
- nxt_registry (0.1.4)
31
+ method_source (1.0.0)
32
+ minitest (5.14.1)
33
+ nxt_registry (0.2.0)
34
34
  activesupport
35
35
  nxt_vcr_harness (0.1.3)
36
36
  rspec (~> 3.0)
37
37
  vcr (~> 5.0)
38
- pry (0.12.2)
39
- coderay (~> 1.1.0)
40
- method_source (~> 0.9.0)
41
- public_suffix (4.0.1)
42
- rake (10.5.0)
43
- redis (4.1.3)
38
+ pry (0.13.1)
39
+ coderay (~> 1.1)
40
+ method_source (~> 1.0)
41
+ public_suffix (4.0.3)
42
+ rake (13.0.1)
43
+ redis (4.2.1)
44
44
  rspec (3.9.0)
45
45
  rspec-core (~> 3.9.0)
46
46
  rspec-expectations (~> 3.9.0)
@@ -54,18 +54,20 @@ GEM
54
54
  diff-lcs (>= 1.2.0, < 2.0)
55
55
  rspec-support (~> 3.9.0)
56
56
  rspec-support (3.9.0)
57
+ rspec_junit_formatter (0.4.1)
58
+ rspec-core (>= 2, < 4, != 2.12.0)
57
59
  safe_yaml (1.0.5)
58
60
  thread_safe (0.3.6)
59
- typhoeus (1.3.1)
61
+ typhoeus (1.4.0)
60
62
  ethon (>= 0.9.0)
61
- tzinfo (1.2.6)
63
+ tzinfo (1.2.7)
62
64
  thread_safe (~> 0.1)
63
- vcr (5.0.0)
64
- webmock (3.7.6)
65
+ vcr (5.1.0)
66
+ webmock (3.8.3)
65
67
  addressable (>= 2.3.6)
66
68
  crack (>= 0.3.2)
67
69
  hashdiff (>= 0.4.0, < 2.0.0)
68
- zeitwerk (2.2.2)
70
+ zeitwerk (2.4.0)
69
71
 
70
72
  PLATFORMS
71
73
  ruby
@@ -75,9 +77,10 @@ DEPENDENCIES
75
77
  nxt_http_client!
76
78
  nxt_vcr_harness
77
79
  pry
78
- rake (~> 10.0)
80
+ rake (~> 13.0)
79
81
  redis
80
82
  rspec (~> 3.0)
83
+ rspec_junit_formatter
81
84
  vcr
82
85
  webmock
83
86
 
data/README.md CHANGED
@@ -43,6 +43,7 @@ class MyClient < NxtHttpClient
43
43
 
44
44
  register_response_handler do |handler|
45
45
  handler.on(:error) do |response|
46
+ Raven.extra_context(error_details: error.to_h) # call error.to_h to inspect request and response
46
47
  raise StandardError, "I can't handle this: #{response.code}"
47
48
  end
48
49
  end
@@ -1,51 +1,22 @@
1
1
  module NxtHttpClient
2
2
  class Client
3
3
  extend ClientDsl
4
- CACHE_STRATEGIES = %w[global thread]
4
+ CACHE_STRATEGIES = %w[global thread].freeze
5
+ HTTP_METHODS = %w[get post patch put delete head].freeze
5
6
 
6
7
  def build_request(url, **opts)
7
- base_url = opts.delete(:base_url) || default_config.base_url
8
- url = [base_url, url].reject(&:blank?).join('/')
9
-
10
- duplicated_slashes = url.match(/([^:]\/{2,})/)
11
- duplicated_slashes && duplicated_slashes.captures.each do |capture|
12
- url.gsub!(capture, "#{capture[0]}/")
13
- end
14
-
15
- opts = default_config.request_options.with_indifferent_access.deep_merge(opts.with_indifferent_access)
16
- opts[:headers] ||= {}
17
-
18
- if default_config.x_request_id_proc
19
- opts[:headers]['X-Request-ID'] ||= default_config.x_request_id_proc.call
20
- end
21
-
22
- if opts[:cache] ||= false
23
- strategy = opts.delete(:cache)
24
-
25
- case strategy.to_s
26
- when 'thread'
27
- cache_key = Thread.current[:nxt_http_client_cache_key] ||= "#{SecureRandom.base58}::#{DateTime.current}"
28
- opts[:headers].reverse_merge!(cache_key: cache_key)
29
- when 'global'
30
- opts[:headers].delete(:cache_key)
31
- else
32
- raise ArgumentError, "Cache strategy unknown: #{strategy}. Options are #{CACHE_STRATEGIES}"
33
- end
34
- end
8
+ url = build_url(opts, url)
9
+ opts = build_headers(opts)
35
10
 
36
11
  Typhoeus::Request.new(url, **opts.symbolize_keys)
37
12
  end
38
13
 
39
- def fire(url = '', **opts, &block)
40
- # calling_method = caller_locations(1,1)[0].label
41
- response_handler = opts.fetch(:response_handler) do
42
- dup_handler_from_class || NxtHttpClient::ResponseHandler.new
43
- end
14
+ delegate :before_fire_callback, :after_fire_callback, to: :class
44
15
 
16
+ def fire(url = '', **opts, &block)
17
+ response_handler = opts.fetch(:response_handler) { dup_handler_from_class || NxtHttpClient::ResponseHandler.new }
45
18
  response_handler.configure(&block) if block_given?
46
- request = build_request(url, opts.except(:response_handler))
47
-
48
- before_fire_callback = self.class.before_fire_callback
19
+ request = build_request(url, **opts.except(:response_handler))
49
20
  before_fire_callback && instance_exec(self, request, response_handler, &before_fire_callback)
50
21
 
51
22
  if response_handler.callbacks['headers']
@@ -61,20 +32,17 @@ module NxtHttpClient
61
32
  end
62
33
 
63
34
  result = nil
64
- error = nil
35
+ current_error = nil
65
36
 
66
37
  request.on_complete do |response|
67
- callback = response_handler.callback_for_response(response)
68
- result = callback && instance_exec(response, &callback) || response
69
- rescue StandardError => e
70
- error = e
38
+ result = callback_or_response(response, response_handler)
39
+ rescue StandardError => error
40
+ current_error = error
71
41
  ensure
72
- after_fire_callback = self.class.after_fire_callback
73
-
74
42
  if after_fire_callback
75
- result = instance_exec(self, request, response, result, error, &after_fire_callback)
43
+ result = instance_exec(self, request, response, result, current_error, &after_fire_callback)
76
44
  else
77
- result || (raise error)
45
+ result || (raise current_error)
78
46
  end
79
47
  end
80
48
 
@@ -83,10 +51,32 @@ module NxtHttpClient
83
51
  result
84
52
  end
85
53
 
86
- %w[get post patch put delete head].each do |method|
54
+ HTTP_METHODS.each do |method|
87
55
  define_method method do |url = '', **opts, &block|
88
- fire(url, opts.reverse_merge(method: method), &block)
56
+ fire(url, **opts.reverse_merge(method: method), &block)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def build_url(opts, url)
63
+ base_url = opts.delete(:base_url) || default_config.base_url
64
+ url = [base_url, url].reject(&:blank?).join('/')
65
+
66
+ url_without_duplicated_hashes(url)
67
+ url
68
+ end
69
+
70
+ def build_headers(opts)
71
+ opts = default_config.request_options.with_indifferent_access.deep_merge(opts.with_indifferent_access)
72
+ opts[:headers] ||= {}
73
+
74
+ if default_config.x_request_id_proc
75
+ opts[:headers]['X-Request-ID'] ||= default_config.x_request_id_proc.call
89
76
  end
77
+
78
+ build_cache_header(opts)
79
+ opts
90
80
  end
91
81
 
92
82
  def dup_handler_from_class
@@ -96,5 +86,35 @@ module NxtHttpClient
96
86
  def default_config
97
87
  self.class.default_config
98
88
  end
89
+
90
+ def build_cache_header(opts)
91
+ if opts[:cache] ||= false
92
+ strategy = opts.delete(:cache)
93
+
94
+ case strategy.to_s
95
+ when 'thread'
96
+ cache_key = Thread.current[:nxt_http_client_cache_key] ||= "#{SecureRandom.base58}::#{DateTime.current}"
97
+ opts[:headers].reverse_merge!(cache_key: cache_key)
98
+ when 'global'
99
+ opts[:headers].delete(:cache_key)
100
+ else
101
+ raise ArgumentError, "Cache strategy unknown: #{strategy}. Options are #{CACHE_STRATEGIES}"
102
+ end
103
+ end
104
+ end
105
+
106
+ def url_without_duplicated_hashes(url)
107
+ duplicated_slashes = url.match(/([^:]\/{2,})/)
108
+ duplicated_slashes && duplicated_slashes.captures.each do |capture|
109
+ url.gsub!(capture, "#{capture[0]}/")
110
+ end
111
+
112
+ url
113
+ end
114
+
115
+ def callback_or_response(response, response_handler)
116
+ callback = response_handler.callback_for_response(response)
117
+ callback && instance_exec(response, &callback) || response
118
+ end
99
119
  end
100
120
  end
@@ -1,9 +1,7 @@
1
1
  module NxtHttpClient
2
2
  module ClientDsl
3
3
  def configure(opts = {}, &block)
4
- opts.each do |k,v|
5
- default_config.send(k, v)
6
- end
4
+ opts.each { |k, v| default_config.send(k, v) }
7
5
  default_config.tap { |d| block.call(d) }
8
6
  default_config
9
7
  end
@@ -13,7 +11,7 @@ module NxtHttpClient
13
11
  end
14
12
 
15
13
  def before_fire_callback
16
- @before_fire ||= dup_instance_variable_from_ancestor_chain(:@before_fire_callback)
14
+ @before_fire_callback ||= dup_instance_variable_from_ancestor_chain(:@before_fire_callback)
17
15
  end
18
16
 
19
17
  def after_fire(&block)
@@ -44,21 +42,16 @@ module NxtHttpClient
44
42
  end
45
43
 
46
44
  def instance_variable_from_ancestor_chain(instance_variable_name)
47
- client = client_ancestors.find do |client|
48
- client.instance_variable_get(instance_variable_name)
49
- end
45
+ client = client_ancestors.find { |c| c.instance_variable_get(instance_variable_name) }
50
46
 
51
47
  client.instance_variable_get(instance_variable_name)
52
48
  end
53
49
 
54
50
  def dup_instance_variable_from_ancestor_chain(instance_variable_name)
55
51
  result = instance_variable_from_ancestor_chain(instance_variable_name).dup
52
+ return result unless block_given?
56
53
 
57
- if block_given?
58
- result || yield
59
- else
60
- result
61
- end
54
+ result || yield
62
55
  end
63
56
  end
64
57
  end
@@ -1,5 +1,5 @@
1
1
  module NxtHttpClient
2
- CONFIGURABLE_OPTIONS = %i[request_options base_url x_request_id_proc]
2
+ CONFIGURABLE_OPTIONS = %i[request_options base_url x_request_id_proc].freeze
3
3
 
4
4
  DefaultConfig = Struct.new('DefaultConfig', *CONFIGURABLE_OPTIONS) do
5
5
  def initialize(request_options: ActiveSupport::HashWithIndifferentAccess.new, base_url: '', x_request_id_proc: nil)
@@ -2,9 +2,10 @@ module NxtHttpClient
2
2
  class Error < StandardError
3
3
  def initialize(response)
4
4
  @response = response.blank? ? Typhoeus::Response.new : response
5
+ @id = SecureRandom.uuid
5
6
  end
6
7
 
7
- attr_reader :response
8
+ attr_reader :response, :id
8
9
 
9
10
  def to_s
10
11
  "NxtHttpClient::Error::#{response_code}"
@@ -12,6 +13,7 @@ module NxtHttpClient
12
13
 
13
14
  def to_h
14
15
  {
16
+ id: id,
15
17
  url: url,
16
18
  response_code: response_code,
17
19
  request_options: request_options,
@@ -4,20 +4,14 @@ module NxtHttpClient
4
4
  include NxtRegistry
5
5
 
6
6
  def initialize
7
- @callbacks = registry(
8
- :callbacks,
9
- call: false,
10
- on_key_already_registered: ->(key) { raise_callback_already_registered(key) }
11
- )
12
-
13
7
  @result = nil
14
8
  end
15
9
 
16
10
  attr_accessor :result
17
- attr_reader :callbacks
18
11
 
19
12
  def eval_callback(target, key, response)
20
13
  return unless callbacks.resolve!(key)
14
+
21
15
  target.instance_exec(response, &callbacks.resolve(key))
22
16
  end
23
17
 
@@ -37,8 +31,8 @@ module NxtHttpClient
37
31
  register_callback(code, overwrite: true, &block)
38
32
  end
39
33
 
40
- alias_method :on, :register_callback
41
- alias_method :on!, :register_callback!
34
+ alias on register_callback
35
+ alias on! register_callback!
42
36
 
43
37
  def callback_for_response(response)
44
38
  key_from_response = response.code.to_s
@@ -50,10 +44,18 @@ module NxtHttpClient
50
44
  end
51
45
 
52
46
  first_matching_key && callbacks[first_matching_key] ||
53
- response.success? && callbacks['success'] ||
54
- response.timed_out? && callbacks['timed_out'] ||
55
- !response.success? && callbacks['error'] ||
56
- callbacks['others']
47
+ response.success? && callbacks['success'] ||
48
+ response.timed_out? && callbacks['timed_out'] ||
49
+ !response.success? && callbacks['error'] ||
50
+ callbacks['others']
51
+ end
52
+
53
+ def callbacks
54
+ @callbacks ||= NxtRegistry::Registry.new(
55
+ :callbacks,
56
+ call: false,
57
+ on_key_already_registered: ->(key) { raise_callback_already_registered(key) }
58
+ )
57
59
  end
58
60
 
59
61
  private
@@ -1,3 +1,3 @@
1
1
  module NxtHttpClient
2
- VERSION = "0.2.9"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -40,11 +40,12 @@ Gem::Specification.new do |spec|
40
40
  spec.add_dependency 'nxt_registry'
41
41
 
42
42
  spec.add_development_dependency 'bundler', '~> 1.17'
43
- spec.add_development_dependency 'rake', '~> 10.0'
43
+ spec.add_development_dependency 'rake', '~> 13.0'
44
44
  spec.add_development_dependency 'rspec', '~> 3.0'
45
45
  spec.add_development_dependency 'pry'
46
46
  spec.add_development_dependency 'vcr'
47
47
  spec.add_development_dependency 'webmock'
48
48
  spec.add_development_dependency 'nxt_vcr_harness'
49
49
  spec.add_development_dependency 'redis'
50
+ spec.add_development_dependency 'rspec_junit_formatter'
50
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_http_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Robecke
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-01-15 00:00:00.000000000 Z
14
+ date: 2020-07-30 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: typhoeus
@@ -75,14 +75,14 @@ dependencies:
75
75
  requirements:
76
76
  - - "~>"
77
77
  - !ruby/object:Gem::Version
78
- version: '10.0'
78
+ version: '13.0'
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
83
  - - "~>"
84
84
  - !ruby/object:Gem::Version
85
- version: '10.0'
85
+ version: '13.0'
86
86
  - !ruby/object:Gem::Dependency
87
87
  name: rspec
88
88
  requirement: !ruby/object:Gem::Requirement
@@ -167,6 +167,20 @@ dependencies:
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
+ - !ruby/object:Gem::Dependency
171
+ name: rspec_junit_formatter
172
+ requirement: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ type: :development
178
+ prerelease: false
179
+ version_requirements: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
170
184
  description: NxtHttpClinet allows you to easily create and configure http clients.
171
185
  email:
172
186
  - a.robecke@getsafe.de
@@ -174,9 +188,11 @@ executables: []
174
188
  extensions: []
175
189
  extra_rdoc_files: []
176
190
  files:
191
+ - ".circleci/config.yml"
177
192
  - ".gitignore"
178
193
  - ".rspec"
179
194
  - ".travis.yml"
195
+ - CHANGELOG.md
180
196
  - Gemfile
181
197
  - Gemfile.lock
182
198
  - LICENSE.txt
@@ -214,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
214
230
  - !ruby/object:Gem::Version
215
231
  version: '0'
216
232
  requirements: []
217
- rubygems_version: 3.0.6
233
+ rubygems_version: 3.0.3
218
234
  signing_key:
219
235
  specification_version: 4
220
236
  summary: NxtHttpClinet is a simple DSL on top the typhoeus http gem