chimera_http_client 1.1.1 → 1.3.1

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: 245adb27237d0970454580b14f6973ed7bf732a8ce3f4426b35978ff27eed9d8
4
- data.tar.gz: 02e8646e5757b60b7d4617d58f3413bdd4b5675d8d307342fabc7ce03c90471b
3
+ metadata.gz: 0b68f9f3f76d137690c9f3fd9345b835efadee680ba8cd6b964095c554f9cb96
4
+ data.tar.gz: 7a86650670f451558d407c04a9870f522cf6805413f256dfc453622c9c55263f
5
5
  SHA512:
6
- metadata.gz: 0caca4f777876526ab8fb4f1652b0643e545bd768e7722424e2007e3e1e79f397cc043dd5ad81d4319ec0703242c72a9481bcac589a48d82374a7e646cef2974
7
- data.tar.gz: caf3dc496a546c75a07475148a063caf8b312f9fb63f9a65de02577c3f7b4398e8c05660660d003c6dc7a14bf50b33e5e46cba6d7c2599901b265d3df3f5155c
6
+ metadata.gz: 8a12bdf778c260bdfe95f529e7d94dbecf6b0d041f21da25a5f3503c185db8aaaa041d27d01b98767ddb98466e684c2fc266cab3e0bbaf8cb61b7353a8f37071
7
+ data.tar.gz: 7da871e77ae5d29d207c5e6c4d95f3cdc831a15202cf7bf0a3f73ee44c8610ba1760189b542f86ff161b963640d448ac7a28fbeaa04845a1c8f462a28f13245c
@@ -5,46 +5,19 @@ AllCops:
5
5
  - vendor/**/*
6
6
  - config.ru
7
7
 
8
- Layout/AlignHash:
9
- Enabled: false
10
-
11
8
  # Cop supports --auto-correct.
12
9
  # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
13
10
  # SupportedStyles: special_inside_parentheses, consistent, align_braces
14
- Layout/IndentFirstHashElement:
11
+ Layout/FirstHashElementIndentation:
15
12
  EnforcedStyle: consistent
16
13
 
17
- Metrics/AbcSize:
18
- Max: 35
19
-
20
- Metrics/BlockLength:
21
- Exclude:
22
- - chimera_http_client.gemspec
23
- - spec/**/*
24
-
25
- # Configuration parameters: CountComments.
26
- Metrics/ClassLength:
27
- Max: 150
28
-
29
- Metrics/CyclomaticComplexity:
30
- Max: 15
14
+ Layout/HashAlignment:
15
+ Enabled: false
31
16
 
32
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
33
- # URISchemes: http, https
34
- Metrics/LineLength:
17
+ Layout/LineLength:
35
18
  Max: 125
36
19
 
37
- # Offense count: 5
38
- # Configuration parameters: CountComments.
39
- Metrics/MethodLength:
40
- Max: 32
41
-
42
- Metrics/ParameterLists:
43
- Max: 7
44
-
45
- # Configuration parameters: EnforcedStyle, SupportedStyles.
46
- # SupportedStyles: braces, no_braces, context_dependent
47
- Style/BracesAroundHashParameters:
20
+ Metrics:
48
21
  Enabled: false
49
22
 
50
23
  Style/CommentedKeyword:
@@ -1 +1 @@
1
- 2.6.3
1
+ 2.7.2
@@ -7,6 +7,7 @@ And what works for the internal communication between your own apps, will also w
7
7
  It offers an **easy to learn interface** and **nice error handling**. And it enables you to **queue HTTP requests to run them in parallel** for better performance and simple aggregating of distributed data.
8
8
 
9
9
  [![Build Status](https://travis-ci.com/mediafinger/chimera_http_client.svg?branch=master)](https://travis-ci.com/mediafinger/chimera_http_client)
10
+ [![Gem Version](https://badge.fury.io/rb/chimera_http_client.svg)](https://badge.fury.io/rb/chimera_http_client)
10
11
 
11
12
  ## Dependencies
12
13
 
@@ -22,6 +23,8 @@ The only other runtime dependency is Ruby's latest code loader [**zeitwerk**](ht
22
23
  | = 1.0 | >= 2.4 |
23
24
  | <= 0.5 | >= 2.1 |
24
25
 
26
+ The test suite of v1.3 and newer also passes on **JRuby** and on **TruffleRuby**.
27
+
25
28
  ### ENV variables
26
29
 
27
30
  Setting the environment variable `ENV['CHIMERA_HTTP_CLIENT_LOG_REQUESTS']` to `true` (or `'true'`) will provide more detailed error messages for logging and also add additional information to the Error JSON. It is recommended to use this only in development environments.
@@ -82,12 +85,13 @@ Setting the `base_url` is meant to be a comfort feature, as you can then pass sh
82
85
 
83
86
  The optional parameters are:
84
87
 
85
- * `logger` - an instance of a logger class that implements `#info` and `#warn` methods
88
+ * `cache` - an instance of your cache solution, can be overwritten in any request
89
+ * `deserializers` - custom methods to deserialize the response body, below more details
90
+ * `logger` - an instance of a logger class that implements `#info`, `#warn` and `#error` methods
91
+ * `monitor` - to collect metrics about requests, the basis for your instrumentation needs
86
92
  * `timeout` - the timeout for all requests, can be overwritten in any request, the default are 3 seconds
87
93
  * `user_agent` - if you would like your calls to identify with a specific user agent
88
94
  * `verbose` - the default is `false`, set it to true while debugging issues
89
- * `cache` - an instance of your cache solution, can be overwritten in any request
90
- * `deserializers` - custom methods to deserialize the response body, below more details
91
95
 
92
96
  ##### Custom deserializers
93
97
 
@@ -101,6 +105,23 @@ A Deserializer has to be an object on which the method `call` with the parameter
101
105
 
102
106
  where `body` is the response body (in the default case a JSON object). The class `Deserializer` contains the default objects that are used. They might help you creating your own. Don't forget to make requests with another header than the default `"Content-Type" => "application/json"`, when the API you connect to does not support JSON.
103
107
 
108
+ ##### Monitoring, metrics, instrumentation
109
+
110
+ Pass an object as `:monitor` to a connection that defines the method `call` and accepts a hash as parameter.
111
+
112
+ monitor.call({...})
113
+
114
+ It will receive information about every request as soon as it finished. What you do with this information is up for you to implement.
115
+
116
+ | Field | Description |
117
+ |:---------------|:----------------------------------------------------------------------|
118
+ | `url` | URL of the endpoint that was called |
119
+ | `method` | HTTP method: get, post, ... |
120
+ | `status` | HTTP status code: 200, ... |
121
+ | `runtime` | the time in seconds it took the request to finish |
122
+ | `completed_at` | Time.now.utc.iso8601(3) |
123
+ | `context` | Whatever you pass as `monitoring_context` to the options of a request |
124
+
104
125
  ### Request methods
105
126
 
106
127
  The available methods are:
@@ -141,6 +162,7 @@ All request methods expect a mandatory `endpoint` and an optional hash as parame
141
162
  * `password` - used for a BasicAuth login
142
163
  * `timeout` - set a custom timeout per request (the default is 3 seconds)
143
164
  * `cache` - optionally overwrite the cache store set in `Connection` in any request
165
+ * `monitoring_context` - pass additional information you want to collect with your instrumentation `monitor`
144
166
 
145
167
  Example:
146
168
 
@@ -170,6 +192,17 @@ If you want to use a different timeout, you can pass the key `timeout` when init
170
192
 
171
193
  By default no logging is happening. If you need request logging, you can pass your custom Logger to the key `logger` when initializing the `Connection`. It will write to `logger.info` when starting and when completing a request.
172
194
 
195
+ The message passed to the logger is a hash with the following fields:
196
+
197
+ | Key | Description |
198
+ |:-------------|:--------------------------------------------|
199
+ | `message` | indicator if a call was started or finished |
200
+ | `method` | the HTTP method used |
201
+ | `url` | the requested URL |
202
+ | `code` | HTTP status code |
203
+ | `runtime` | time the request took in ms |
204
+ | `user_agent` | the user_agent used to open the connection |
205
+
173
206
  #### Caching responses
174
207
 
175
208
  To cache all the reponses of a connection, just pass the optional parameter `cache` to its initializer. You can also overwrite the connection's cache configuration by passing the parameter `cache` to any `get` call.
@@ -387,7 +420,10 @@ When updating the version, do not forget to run
387
420
 
388
421
  After checking out the repo, run `bundle install` and then `bundle execute rake` to run the **tests and rubocop**.
389
422
 
390
- > The test suite uses a Sinatra server to make real HTTP requests. It is mounted via Capybara_discoball and running in the same process.
423
+ > The test suite uses a Sinatra server to make real HTTP requests. It is mounted via Capybara_discoball and running in the same process. It is still running reasonably fast (on my MacBook Air):
424
+
425
+ Finished in 2.01 seconds (files took 1.09 seconds to load)
426
+ 824 examples, 0 failures, 7 pending
391
427
 
392
428
  You can also run `rake console` to open an irb session with the `ChimeraHttpClient` pre-loaded that will allow you to experiment.
393
429
 
@@ -14,8 +14,9 @@ _none known_
14
14
  * [x] ~~include the total_time of the requests in the log~~
15
15
  * [x] ~~add (example) to README~~
16
16
  * [ ] add logger.warn / .error for error cases (?)
17
+ * [ ] streamline log message
17
18
 
18
- ### Custom De-serializer
19
+ ### ~~Custom De-serializer~~
19
20
 
20
21
  * [x] ~~allow to pass custom deserializer~~
21
22
  * [x] ~~use custom deserializer in #parsed_body instead of default JSON parsing~~
@@ -39,7 +40,19 @@ _none known_
39
40
  ### Miscellaneous
40
41
 
41
42
  - [ ] Determine by parameter if 3xx Redirects should be handled as an Error or not
42
- - [ ] Add a longer description to the gemspec file
43
+ - [x] ~~Add a longer description to the gemspec file~~
44
+ - [ ] Refactor README to explain simple use case vs. all the powerful options?
45
+
46
+ ### ~~Instrumentation~~
47
+
48
+ - [x] ~~allow to pass object to collect metrics for monitoring~~
49
+ - [x] ~~request URL~~
50
+ - [x] ~~request HTTP method~~
51
+ - [x] ~~request response code~~
52
+ - [x] ~~request datetime~~
53
+ - [x] ~~request runtime~~
54
+ - [x] ~~custom context information per request~~
55
+ - [x] ~~add example to README~~
43
56
 
44
57
  ### Enable more Typhoeus functionality
45
58
 
@@ -84,7 +97,7 @@ _none known_
84
97
  * [x] ~~allow to set custom timeout per call~~
85
98
  * [x] ~~add (example) to README~~
86
99
 
87
- ### Release
100
+ ### ~~Release~~
88
101
 
89
102
  * [x] ~~rename module to have unique namespace~~
90
103
  * [x] ~~release to rubygems to add to the plethora of similar gems~~
@@ -3,13 +3,22 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require "chimera_http_client/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
+ spec.required_ruby_version = ">= 2.5.0" # without Deserializer's `rescue` in block it would be 2.4.4 (because of zeitwerk)
7
+
6
8
  spec.name = "chimera_http_client"
7
9
  spec.version = ChimeraHttpClient::VERSION
8
10
  spec.authors = ["Andreas Finger"]
9
11
  spec.email = ["webmaster@mediafinger.com"]
10
12
 
11
- spec.summary = "Http Client to connect to REST APIs"
12
- spec.description = "General http client functionality to easily connect to JSON endpoints" # TODO: extend and polish
13
+ spec.summary = "General http client functionality to quickly connect to JSON REST API endpoints and any others"
14
+ spec.description = <<~DESCRIPTION
15
+ The Chimera http client offers an easy to learn interface and consistent error handling.
16
+ It is lightweight, fast and enables you to queue HTTP requests to run them in parallel
17
+ for better performance and simple aggregating of distributed data. Despite it's simple
18
+ interface it allows for advanced features like using custom deserializers, loggers,
19
+ caching requests individiually, and instrumentation support (soon to be implemented).
20
+ DESCRIPTION
21
+
13
22
  spec.homepage = "https://github.com/mediafinger/chimera_http_client"
14
23
  spec.license = "MIT"
15
24
 
@@ -8,6 +8,7 @@ module ChimeraHttpClient
8
8
  @base_url = options.fetch(:base_url)
9
9
  @deserializer = default_deserializer.merge(options.fetch(:deserializer, {}))
10
10
  @logger = options[:logger]
11
+ @monitor = options[:monitor]
11
12
  @timeout = options[:timeout]
12
13
 
13
14
  Typhoeus::Config.cache = options[:cache]
@@ -12,11 +12,12 @@ module ChimeraHttpClient
12
12
 
13
13
  def request
14
14
  options = {
15
- logger: @logger,
16
15
  deserializer: @deserializer,
16
+ logger: @logger,
17
+ monitor: @monitor,
17
18
  }
18
19
 
19
- @request ||= Request.new(options)
20
+ Request.new(options)
20
21
  end
21
22
 
22
23
  private
@@ -38,12 +38,13 @@ module ChimeraHttpClient
38
38
  private
39
39
 
40
40
  def create_request(method:, url:, body:, headers:, options:)
41
- class_options = {
42
- logger: @logger,
41
+ instance_options = {
43
42
  deserializer: @deserializer,
43
+ logger: @logger,
44
+ monitor: @monitor,
44
45
  }
45
46
 
46
- Request.new(class_options).create(
47
+ Request.new(instance_options).create(
47
48
  method: method,
48
49
  url: url,
49
50
  body: body,
@@ -5,7 +5,6 @@ module ChimeraHttpClient
5
5
  attr_reader :request, :result
6
6
 
7
7
  def initialize(options = {})
8
- @logger = options[:logger]
9
8
  @options = options
10
9
  end
11
10
 
@@ -37,13 +36,39 @@ module ChimeraHttpClient
37
36
 
38
37
  @result = nil
39
38
  @request.on_complete do |response|
40
- @logger&.info("Completed HTTP request: #{method.upcase} #{url} " \
41
- "in #{response.total_time&.round(3)}sec with status code #{response.code}")
39
+ runtime = response.total_time&.round(3)
40
+
41
+ @options[:monitor]&.call(
42
+ {
43
+ url: url, method: method, status: response.code, runtime: runtime,
44
+ completed_at: Time.now.utc.iso8601(3), context: options[:monitoring_context]
45
+ }
46
+ )
47
+
48
+ @options[:logger]&.info(
49
+ {
50
+ message: "Completed Chimera HTTP Request",
51
+ method: method.upcase,
52
+ url: url,
53
+ code: response.code,
54
+ runtime: runtime,
55
+ user_agent: Typhoeus::Config.user_agent,
56
+ }
57
+ )
42
58
 
43
59
  @result = on_complete_handler(response)
44
60
  end
45
61
 
46
- @logger&.info("Starting HTTP request: #{method.upcase} #{url}")
62
+ @options[:logger]&.info(
63
+ {
64
+ message: "Starting Chimera HTTP Request",
65
+ method: method.upcase,
66
+ url: url,
67
+ code: nil,
68
+ runtime: 0,
69
+ user_agent: Typhoeus::Config.user_agent,
70
+ }
71
+ )
47
72
 
48
73
  self
49
74
  end
@@ -63,7 +88,7 @@ module ChimeraHttpClient
63
88
  when 301, 302, 303, 307
64
89
  RedirectionError.new(response, @options) # TODO: throw error conditionally
65
90
  when 200..399
66
- nil
91
+ nil # TODO: decide to either raise error or return a Response
67
92
  when 400
68
93
  BadRequestError.new(response, @options)
69
94
  when 401
@@ -1,3 +1,3 @@
1
1
  module ChimeraHttpClient
2
- VERSION = "1.1.1".freeze
2
+ VERSION = "1.3.1".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chimera_http_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Finger
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-15 00:00:00.000000000 Z
11
+ date: 2021-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -220,7 +220,12 @@ dependencies:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
222
  version: '3.0'
223
- description: General http client functionality to easily connect to JSON endpoints
223
+ description: |
224
+ The Chimera http client offers an easy to learn interface and consistent error handling.
225
+ It is lightweight, fast and enables you to queue HTTP requests to run them in parallel
226
+ for better performance and simple aggregating of distributed data. Despite it's simple
227
+ interface it allows for advanced features like using custom deserializers, loggers,
228
+ caching requests individiually, and instrumentation support (soon to be implemented).
224
229
  email:
225
230
  - webmaster@mediafinger.com
226
231
  executables: []
@@ -251,7 +256,7 @@ homepage: https://github.com/mediafinger/chimera_http_client
251
256
  licenses:
252
257
  - MIT
253
258
  metadata: {}
254
- post_install_message:
259
+ post_install_message:
255
260
  rdoc_options: []
256
261
  require_paths:
257
262
  - lib
@@ -259,15 +264,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
259
264
  requirements:
260
265
  - - ">="
261
266
  - !ruby/object:Gem::Version
262
- version: '0'
267
+ version: 2.5.0
263
268
  required_rubygems_version: !ruby/object:Gem::Requirement
264
269
  requirements:
265
270
  - - ">="
266
271
  - !ruby/object:Gem::Version
267
272
  version: '0'
268
273
  requirements: []
269
- rubygems_version: 3.0.3
270
- signing_key:
274
+ rubygems_version: 3.1.4
275
+ signing_key:
271
276
  specification_version: 4
272
- summary: Http Client to connect to REST APIs
277
+ summary: General http client functionality to quickly connect to JSON REST API endpoints
278
+ and any others
273
279
  test_files: []