eezee 1.0.7
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +282 -0
- data/lib/eezee/client/builder.rb +70 -0
- data/lib/eezee/client/requester.rb +77 -0
- data/lib/eezee/client.rb +13 -0
- data/lib/eezee/configuration.rb +25 -0
- data/lib/eezee/errors/error.rb +6 -0
- data/lib/eezee/errors/request_error.rb +32 -0
- data/lib/eezee/errors/required_field_error.rb +19 -0
- data/lib/eezee/errors/timeout_error.rb +16 -0
- data/lib/eezee/errors.rb +6 -0
- data/lib/eezee/logger.rb +33 -0
- data/lib/eezee/request.rb +97 -0
- data/lib/eezee/request_error_factory.rb +31 -0
- data/lib/eezee/response.rb +60 -0
- data/lib/eezee/version.rb +5 -0
- data/lib/eezee.rb +22 -0
- data/lib/generators/katinguele/install_generator.rb +32 -0
- metadata +283 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '091f04a358ff0034437fb934f267c82e74ee10109c3f9f9a89625e3cbcb464bf'
|
4
|
+
data.tar.gz: 413ad4f550a63cfebd4e688181369264a423f26bfa8fc2b3e1496b3c5552978c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cb1b44f8219ba5bca6b40703c066f3c3da4ff681ac5cd005599866389d9a30bccdc7b52a2e708da8fd99d8adb0846280f3d71c07a30387671a9db2b98738e331
|
7
|
+
data.tar.gz: 89eef48f82b9a9cd284e2332cdfc2de54a187624c961ae7f8600bbed90e6b68f8f439f6930856e30d19298ed575969531987cb70fa1df513a65cd4e335e8c111
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2019 Linqueta
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
# [Eezee][gem_page]
|
2
|
+
|
3
|
+
[![Gem Version][gem_version_image]][gem_version_page]
|
4
|
+
[![Build Status][travis_status_image]][travis_page]
|
5
|
+
[![Maintainability][code_climate_maintainability_image]][code_climate_maintainability_page]
|
6
|
+
[![Test Coverage][code_climate_test_coverage_image]][code_climate_test_coverage_page]
|
7
|
+
|
8
|
+
The easiest HTTP client for Ruby
|
9
|
+
|
10
|
+
With Eezee you can do these things:
|
11
|
+
* Define external services in an initializer file and use them through a simple method
|
12
|
+
* Take HTTP requests just extending a module and call the HTTP request method in your class/module
|
13
|
+
* Set before and after hooks to handle your requests, responses, and errors
|
14
|
+
* Handle all requests, responses, and errors in the same way
|
15
|
+
* Log the request, response, and errors
|
16
|
+
* Set general request timeout and open connection timeout
|
17
|
+
* Raise errors in failed requests
|
18
|
+
* Spend more time coding your API integrations instead defining and testing HTTP settings and clients
|
19
|
+
|
20
|
+
This gem is supported for Ruby 2.6+ applications
|
21
|
+
|
22
|
+
## Table of Contents
|
23
|
+
- [Getting started](#getting-started)
|
24
|
+
- [Installation](#installation)
|
25
|
+
- [Supported HTTP Methods](#supported-http-methods)
|
26
|
+
- [How to take a request](#how-to-take-a-request)
|
27
|
+
- [Request options](#request-options)
|
28
|
+
- [Available Request options](#available-request-options)
|
29
|
+
- [Services](#services)
|
30
|
+
- [How a service works](#how-a-service-works)
|
31
|
+
- [Request](#response)
|
32
|
+
- [Response](#response)
|
33
|
+
- [Errors](#errors)
|
34
|
+
- [Examples](#examples)
|
35
|
+
- [Complete integrations](#complete-integrations)
|
36
|
+
- [Hooks](#hooks)
|
37
|
+
- [Timeout](#timeout)
|
38
|
+
- [Logging](#logging)
|
39
|
+
- [Why use Eezee instead Faraday](#why-use-eezee-instead-faraday)
|
40
|
+
- [Contributing](#contributing)
|
41
|
+
- [License](#license)
|
42
|
+
|
43
|
+
## Getting started
|
44
|
+
|
45
|
+
### Installation
|
46
|
+
|
47
|
+
Add this line to your application's Gemfile:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
gem 'eezee'
|
51
|
+
```
|
52
|
+
|
53
|
+
If you're on Rails you can run this line below to create the initializer:
|
54
|
+
|
55
|
+
```shell
|
56
|
+
rails generator eezee:install
|
57
|
+
```
|
58
|
+
|
59
|
+
### Supported HTTP Methods
|
60
|
+
|
61
|
+
Eezee supports these HTTP methods:
|
62
|
+
|
63
|
+
- GET
|
64
|
+
- POST
|
65
|
+
- PATCH
|
66
|
+
- PUT
|
67
|
+
- DELETE
|
68
|
+
|
69
|
+
And here are the corresponding Eezee's HTTP methods:
|
70
|
+
|
71
|
+
- get(request_options)
|
72
|
+
- post(request_options)
|
73
|
+
- patch(request_options)
|
74
|
+
- put(request_options)
|
75
|
+
- delete(request_options)
|
76
|
+
|
77
|
+
OBS: The param `request_options` is optional.
|
78
|
+
|
79
|
+
### How to take a request
|
80
|
+
|
81
|
+
To take a request using any of these methods you just have to call the HTTP method, and if you want, you can pass the options.
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
module RickMorty::Resource::Character
|
85
|
+
extend Eezee::Client
|
86
|
+
|
87
|
+
def self.index
|
88
|
+
get(url: 'rickandmortyapi.com/api', protocol: :https, path: 'character')
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.find(id)
|
92
|
+
get(
|
93
|
+
url: 'rickandmortyapi.com/api',
|
94
|
+
protocol: :https,
|
95
|
+
path: 'character/:character_id',
|
96
|
+
params: { character_id: id }
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.create(payload)
|
101
|
+
post(
|
102
|
+
url: 'rickandmortyapi.com/api',
|
103
|
+
protocol: :https,
|
104
|
+
path: 'character',
|
105
|
+
payload: payload
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.update(id, payload)
|
110
|
+
post(
|
111
|
+
url: 'rickandmortyapi.com/api',
|
112
|
+
protocol: :https,
|
113
|
+
path: 'character/:character_id',
|
114
|
+
params: { character_id: id }
|
115
|
+
payload: payload
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.destroy(id)
|
120
|
+
delete(
|
121
|
+
url: 'rickandmortyapi.com/api',
|
122
|
+
protocol: :https,
|
123
|
+
path: 'character/:character_id',
|
124
|
+
params: { character_id: id }
|
125
|
+
)
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
### Request options
|
130
|
+
|
131
|
+
Request options are the request settings. They can be used to define services, request options and as a param when you take the HTTP request. For example:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
module RickMorty::Resource::Character
|
135
|
+
extend Eezee::Client
|
136
|
+
|
137
|
+
eezee_request_options protocol: :https,
|
138
|
+
url: 'rickandmortyapi.com/api'
|
139
|
+
path: 'character/:character_id'
|
140
|
+
|
141
|
+
def self.index
|
142
|
+
get
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.find(id)
|
146
|
+
get(params: { character_id: id })
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.update(id, payload)
|
150
|
+
put(
|
151
|
+
params: { character_id: id },
|
152
|
+
payload: payload,
|
153
|
+
after: ->(_req, res) { do_something!(res) }
|
154
|
+
)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
The method `eezee_request_options` can receive all of [Available Request options](#available-request-options).
|
160
|
+
|
161
|
+
When the HTTP methods were called, Eezee has created a Request setting with the options defined in the module and merge with the options passed as a param in the HTTP methods.
|
162
|
+
|
163
|
+
#### Available Request options
|
164
|
+
|
165
|
+
Here are the list of available options and about them:
|
166
|
+
|
167
|
+
| Option | Required | Default | What is it? | Example |
|
168
|
+
|--------|----------|---------|-------------|---------|
|
169
|
+
| `url` | Yes | `nil` | The request's url | `"rickandmortyapi.com/api"` |
|
170
|
+
| `protocol` | No | `nil` | The request's protocol | `:https` |
|
171
|
+
| `path` | No | `nil` | The resource's path | `"characters\:characted_id\addresses"` |
|
172
|
+
| `headers` | No | `{}` | The request's headers. | `{ Token: "Bearer 1a8then..." }` |
|
173
|
+
| `params` | No | `{}` | The query params. If the url or path has a nested param like `:character_id` and you pass it in the hash, this value will be replaced. In the opposite, the value will be concatenated in the url like `...?character_id=10&...`| `{ character_id: 10 }`|
|
174
|
+
| `payload` | No | `{}` | The request's payload | `{ name: "Linqueta", gender: "male" }` |
|
175
|
+
| `before` | No | `nil` | It's the before hook. You can pass Proc or Lambda to handle the request settings. See more in [Hooks](#hooks). | `->(req) { merge_new_headers! }` |
|
176
|
+
| `after` | No | `nil` | It's the after hook. You can pass Proc or Lambda to handle the request settings, response or error after the request. If it returns a valid value (different of false or `nil`) and the request raises an error, the error won't be raised to your application. See more in [Hooks](#hooks). | `->(req, res, err) { do_something! }` |
|
177
|
+
| `timeout` | No | `nil` | If it exceeds this timeout to make whole request Eezee will raise the error `Eezee::TimeoutError` | `5` |
|
178
|
+
| `open_timeout` | No | `nil` | If it exceed this timeout to open a connection Eezee will raise the error `Eezee::TimeoutError` | `2` |
|
179
|
+
| `raise_error` | No | `false` | If you want that Eezee raises an error if the request has wasn't successful. See more in [Errors](#errors) | `true` |
|
180
|
+
| `logger` | No | `false` | If you want to log the request, response, and error | `true` |
|
181
|
+
|
182
|
+
### Services
|
183
|
+
|
184
|
+
It's common your app has integrations with many external services and this gem has a feature to organize in one file the settings of these external service integrations and it provides an easy way to get these settings.
|
185
|
+
|
186
|
+
For example, I will integrate with [Rick and Morty Api](https://rickandmortyapi.com/api/) using a service:
|
187
|
+
|
188
|
+
- I'll declare it in an initializer file:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
Eezee.configure do |config|
|
192
|
+
config.add_service :rick_morty_api,
|
193
|
+
protocol: :https,
|
194
|
+
url: 'rickandmortyapi.com/api'
|
195
|
+
end
|
196
|
+
```
|
197
|
+
|
198
|
+
- In my resource, I'll catch the service and pass other settings:
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
module RickMorty::Resource::Character
|
202
|
+
extend Eezee::Client
|
203
|
+
|
204
|
+
eezee_service :rick_morty_api
|
205
|
+
eezee_request_options path: 'character/:character_id'
|
206
|
+
|
207
|
+
def self.index
|
208
|
+
get
|
209
|
+
end
|
210
|
+
|
211
|
+
def self.find(id)
|
212
|
+
get(params: { character_id: id })
|
213
|
+
end
|
214
|
+
end
|
215
|
+
```
|
216
|
+
|
217
|
+
#### How a service works
|
218
|
+
|
219
|
+
When Ruby loads a class/module and it has the method `eezee_service` declared with a service's name, by default, Eezee will try load the service and create a request base for the class/module, so, when the class/module takes a request, Eezee will create the final request instance based on request base to take the HTTP request. You can turn it lazy setting the option `lazy: true`, therefore, the final request will be created just in the HTTP request. If the service doesn't exist when Eezee search about it, it will be raised the error `Eezee::Client::UnknownService`.
|
220
|
+
|
221
|
+
About the method `add_service`, you can pass all of [Available Request options](#available-request-options). The meaning of this part is to organize in one way the external services integrations.
|
222
|
+
|
223
|
+
### Request
|
224
|
+
|
225
|
+
Coming soon...
|
226
|
+
|
227
|
+
### Response
|
228
|
+
|
229
|
+
Coming soon...
|
230
|
+
|
231
|
+
### Errors
|
232
|
+
|
233
|
+
Coming soon...
|
234
|
+
|
235
|
+
### Examples
|
236
|
+
|
237
|
+
Here are some examples:
|
238
|
+
|
239
|
+
#### Complete integrations
|
240
|
+
|
241
|
+
Coming soon...
|
242
|
+
|
243
|
+
#### Hooks
|
244
|
+
|
245
|
+
Coming soon...
|
246
|
+
|
247
|
+
#### Timeout
|
248
|
+
|
249
|
+
Coming soon...
|
250
|
+
|
251
|
+
#### Logging
|
252
|
+
|
253
|
+
Coming soon...
|
254
|
+
|
255
|
+
## Why use Eezee instead Faraday
|
256
|
+
|
257
|
+
Coming soon...
|
258
|
+
|
259
|
+
## Contributing
|
260
|
+
|
261
|
+
1. Fork it
|
262
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
263
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
264
|
+
4. Push to the branch (git push origin my-new-feature)
|
265
|
+
5. Create new Pull Request
|
266
|
+
|
267
|
+
## License
|
268
|
+
|
269
|
+
The gem is available as open source under the terms of the [MIT License][mit_license_page].
|
270
|
+
|
271
|
+
[gem_page]: https://github.com/linqueta/eezee
|
272
|
+
[code_of_conduct_page]: https://github.com/linqueta/eezee/blob/master/CODE_OF_CONDUCT.md
|
273
|
+
[mit_license_page]: https://opensource.org/licenses/MIT
|
274
|
+
[contributor_convenant_page]: http://contributor-covenant.org
|
275
|
+
[travis_status_image]: https://travis-ci.org/linqueta/eezee.svg?branch=master
|
276
|
+
[travis_page]: https://travis-ci.org/linqueta/eezee
|
277
|
+
[code_climate_maintainability_image]: https://api.codeclimate.com/v1/badges/b3ae18295c290b6a92a9/maintainability
|
278
|
+
[code_climate_maintainability_page]: https://codeclimate.com/github/linqueta/eezee/maintainability
|
279
|
+
[code_climate_test_coverage_image]: https://api.codeclimate.com/v1/badges/b3ae18295c290b6a92a9/test_coverage
|
280
|
+
[code_climate_test_coverage_page]: https://codeclimate.com/github/linqueta/eezee/test_coverage
|
281
|
+
[gem_version_image]: https://badge.fury.io/rb/eezee.svg
|
282
|
+
[gem_version_page]: https://rubygems.org/gems/eezee
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
module Client
|
5
|
+
class UnknownService < StandardError; end
|
6
|
+
|
7
|
+
module Builder
|
8
|
+
def self.extended(base)
|
9
|
+
base.send(:build_eezee_options)
|
10
|
+
base.send(:build_eezee_request_attributes)
|
11
|
+
base.eezee_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def eezee_request_options(options)
|
15
|
+
build_eezee_request_options(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def eezee_service(name, options = {})
|
19
|
+
build_eezee_service(name, { lazy: false }.merge(options || {}))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def build_eezee_options
|
25
|
+
define_singleton_method(:eezee_options) { @eezee_options ||= {} }
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_eezee_request_options(options = {})
|
29
|
+
eezee_options[:request_options] ||= options
|
30
|
+
build_eezee_request
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_eezee_service(name = nil, options = {})
|
34
|
+
eezee_options[:service_name] ||= name
|
35
|
+
eezee_options[:service_options] ||= options
|
36
|
+
build_eezee_request
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_eezee_request(force = false)
|
40
|
+
Eezee.configuration
|
41
|
+
.find_service(eezee_options[:service_name])
|
42
|
+
.then { |service| handle_unknown_service!(service, force) }
|
43
|
+
.then { |service| create_request(service, force) }
|
44
|
+
.then { |request| eezee_options[:request] = request }
|
45
|
+
.then { build_eezee_request_attributes }
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_eezee_request_attributes
|
49
|
+
define_singleton_method(:eezee_request_attributes) { eezee_options&.[](:request)&.attributes || {} }
|
50
|
+
end
|
51
|
+
|
52
|
+
def handle_unknown_service!(service, force)
|
53
|
+
return unless take_request?(force)
|
54
|
+
raise UnknownService if !service && eezee_options[:service_name]
|
55
|
+
|
56
|
+
service
|
57
|
+
end
|
58
|
+
|
59
|
+
def take_request?(force)
|
60
|
+
!eezee_options.dig(:service_options, :lazy) || force
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_request(service, force)
|
64
|
+
return unless take_request?(force)
|
65
|
+
|
66
|
+
Eezee.configuration.request_by(service, eezee_options[:request_options])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Eezee
|
7
|
+
module Client
|
8
|
+
module Requester
|
9
|
+
METHODS = %i[get post patch put delete].freeze
|
10
|
+
|
11
|
+
def self.extended(base)
|
12
|
+
METHODS.each do |method|
|
13
|
+
base.send(
|
14
|
+
:define_singleton_method,
|
15
|
+
method,
|
16
|
+
->(options = {}) { eezee_client_request(options, method) }
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def eezee_client_request(options, method)
|
22
|
+
request = build_final_request(options, method)
|
23
|
+
|
24
|
+
build_faraday_client(request)
|
25
|
+
.then { |client| build_faraday_request(request, client, method) }
|
26
|
+
.then { |response| Eezee::Response.new(response) }
|
27
|
+
.tap { |response| response.log if request.logger }
|
28
|
+
.tap { |response| request.after!(request, response, nil) }
|
29
|
+
rescue Faraday::Error => e
|
30
|
+
response = Eezee::Response.new(e)
|
31
|
+
error = Eezee::RequestErrorFactory.build(response)
|
32
|
+
error.log if request.logger
|
33
|
+
return response if rescue_faraday_error?(request, response, error)
|
34
|
+
|
35
|
+
raise error
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_final_request(options, method)
|
39
|
+
build_eezee_request_lazy
|
40
|
+
|
41
|
+
Eezee.configuration
|
42
|
+
.request_by(eezee_options[:request], options)
|
43
|
+
.tap do |request|
|
44
|
+
request.before!(request)
|
45
|
+
request.method = method
|
46
|
+
request.log if request.logger
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_eezee_request_lazy
|
51
|
+
return unless eezee_options.dig(:service_options, :lazy)
|
52
|
+
|
53
|
+
build_eezee_request(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
def rescue_faraday_error?(req, res, err)
|
57
|
+
req.after!(req, res, err) || (err.is_a?(Eezee::TimeoutError) && !req.raise_error)
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_faraday_request(req, client, method)
|
61
|
+
client.send(method) do |faraday_req|
|
62
|
+
faraday_req.body = req.payload.to_json if req.payload
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_faraday_client(request)
|
67
|
+
Faraday.new(request.uri) do |config|
|
68
|
+
config.use(Faraday::Response::RaiseError) if request.raise_error
|
69
|
+
config.headers = request.headers if request.headers
|
70
|
+
config.options[:open_timeout] = request.open_timeout if request.open_timeout
|
71
|
+
config.options[:timeout] = request.timeout if request.timeout
|
72
|
+
config.adapter(Faraday.default_adapter)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/eezee/client.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class Configuration
|
5
|
+
attr_reader :services
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@services = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_service(name, options)
|
12
|
+
return unless name && options
|
13
|
+
|
14
|
+
@services[name] = Request.new(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_service(name)
|
18
|
+
@services[name]
|
19
|
+
end
|
20
|
+
|
21
|
+
def request_by(request, options)
|
22
|
+
Request.new((request&.attributes || {}).merge(options || {}))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class RequestError < Error
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
def initialize(response)
|
8
|
+
@response = response
|
9
|
+
super(build_message)
|
10
|
+
end
|
11
|
+
|
12
|
+
def log
|
13
|
+
Eezee::Logger.error(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def build_message
|
19
|
+
"CODE: #{@response.code} - BODY: #{@response.body.to_json}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class BadRequestError < RequestError; end
|
24
|
+
class UnauthorizedError < RequestError; end
|
25
|
+
class ForbiddenError < RequestError; end
|
26
|
+
class ResourceNotFoundError < RequestError; end
|
27
|
+
class UnprocessableEntityError < RequestError; end
|
28
|
+
class ClientError < RequestError; end
|
29
|
+
class InternalServerError < RequestError; end
|
30
|
+
class ServiceUnavailableError < RequestError; end
|
31
|
+
class ServerError < RequestError; end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class RequiredFieldError < StandardError
|
5
|
+
attr_reader :origin, :field
|
6
|
+
|
7
|
+
def initialize(origin, field)
|
8
|
+
@origin = origin
|
9
|
+
@field = field
|
10
|
+
super(build_message)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_message
|
16
|
+
"The field #{@field} is required for #{@origin}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class TimeoutError < Error
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
def initialize(response)
|
8
|
+
@response = response
|
9
|
+
super(response.original)
|
10
|
+
end
|
11
|
+
|
12
|
+
def log
|
13
|
+
Eezee::Logger.error(self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/eezee/errors.rb
ADDED
data/lib/eezee/logger.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
module Logger
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def request(req, method)
|
8
|
+
p log("request: #{method} #{req.uri}")
|
9
|
+
p log("request: HEADERS: #{req.headers&.to_json}") if req.headers
|
10
|
+
p log("request: PAYLOAD: #{req.payload&.to_json}") if req.payload
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def response(res)
|
15
|
+
p log("response: SUCCESS: #{res.success?}")
|
16
|
+
p log("response: TIMEOUT: #{res.timeout?}")
|
17
|
+
p log("response: CODE: #{res.code}")
|
18
|
+
p log("response: BODY: #{res.body&.to_json}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def error(err)
|
22
|
+
p log("error: #{err.class}")
|
23
|
+
p log("error: SUCCESS: #{err.response.success?}")
|
24
|
+
p log("error: TIMEOUT: #{err.response.timeout?}")
|
25
|
+
p log("error: CODE: #{err.response.code}")
|
26
|
+
p log("error: BODY: #{err.response.body&.to_json}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def log(message)
|
30
|
+
"INFO -- #{message}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class Request
|
5
|
+
ACCESSORS = %i[
|
6
|
+
after
|
7
|
+
before
|
8
|
+
headers
|
9
|
+
logger
|
10
|
+
open_timeout
|
11
|
+
params
|
12
|
+
path
|
13
|
+
payload
|
14
|
+
protocol
|
15
|
+
raise_error
|
16
|
+
timeout
|
17
|
+
url
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
DEFAULT = {
|
21
|
+
headers: {},
|
22
|
+
logger: false,
|
23
|
+
params: {},
|
24
|
+
payload: {},
|
25
|
+
raise_error: false
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
attr_accessor(*(ACCESSORS | %i[uri method]))
|
29
|
+
|
30
|
+
def initialize(options = {})
|
31
|
+
setup!(options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def log
|
35
|
+
Eezee::Logger.request(self, @method.to_s.upcase)
|
36
|
+
end
|
37
|
+
|
38
|
+
def attributes
|
39
|
+
ACCESSORS.each_with_object({}) { |accessor, obj| obj[accessor] = send(accessor) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def before!(*params)
|
43
|
+
hook!(:before, params)
|
44
|
+
end
|
45
|
+
|
46
|
+
def after!(*params)
|
47
|
+
hook!(:after, params)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def setup!(options = {})
|
53
|
+
accessors!(DEFAULT.merge(options || {}))
|
54
|
+
validate!
|
55
|
+
build_urn!
|
56
|
+
handle_query_params!
|
57
|
+
handle_urn_params!
|
58
|
+
end
|
59
|
+
|
60
|
+
def hook!(hook, params)
|
61
|
+
return unless send(hook)&.is_a?(Proc)
|
62
|
+
|
63
|
+
send(hook).call(*params[0..(send(hook).parameters.length - 1)])
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate!
|
67
|
+
raise Eezee::RequiredFieldError.new(self.class, :url) unless @url
|
68
|
+
end
|
69
|
+
|
70
|
+
def accessors!(params)
|
71
|
+
params.slice(*ACCESSORS)
|
72
|
+
.each { |k, v| instance_variable_set("@#{k}", v) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def build_urn!
|
76
|
+
@uri = [@protocol, [@url, @path].compact.join('/')].compact.join('://')
|
77
|
+
end
|
78
|
+
|
79
|
+
def handle_urn_params!
|
80
|
+
return unless @params.is_a?(Hash)
|
81
|
+
|
82
|
+
@params.filter { |k, _v| @uri.include?(":#{k}") }
|
83
|
+
.each { |k, v| @uri.gsub!(":#{k}", v.to_s) }
|
84
|
+
.then { @uri.gsub!(/:[a-z_-]+/, '') }
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_query_params!
|
88
|
+
return unless @params.is_a?(Hash)
|
89
|
+
|
90
|
+
@params.reject { |k, _v| @uri.include?(":#{k}") }
|
91
|
+
.map { |k, v| "#{k}=#{v}" }
|
92
|
+
.then { |array| array.join('&') }
|
93
|
+
.then { |query| query unless query.empty? }
|
94
|
+
.then { |query| @uri = [@uri, query].compact.join('?') }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Eezee
|
4
|
+
class RequestErrorFactory
|
5
|
+
class << self
|
6
|
+
def build(response)
|
7
|
+
return TimeoutError.new(response) if response.timeout?
|
8
|
+
|
9
|
+
find_by_code(response.code).new(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def find_by_code(code)
|
15
|
+
case code
|
16
|
+
when 400 then BadRequestError
|
17
|
+
when 401 then UnauthorizedError
|
18
|
+
when 403 then ForbiddenError
|
19
|
+
when 404 then ResourceNotFoundError
|
20
|
+
when 422 then UnprocessableEntityError
|
21
|
+
when 400..499 then ClientError
|
22
|
+
when 500 then InternalServerError
|
23
|
+
when 503 then ServiceUnavailableError
|
24
|
+
when 500..599 then ServerError
|
25
|
+
else
|
26
|
+
RequestError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'faraday'
|
5
|
+
|
6
|
+
module Eezee
|
7
|
+
class Response
|
8
|
+
attr_reader :original
|
9
|
+
|
10
|
+
def initialize(original)
|
11
|
+
@original = original
|
12
|
+
end
|
13
|
+
|
14
|
+
def body
|
15
|
+
return {} if timeout?
|
16
|
+
|
17
|
+
@body ||= parsed_body
|
18
|
+
end
|
19
|
+
|
20
|
+
def success?
|
21
|
+
return false if timeout?
|
22
|
+
|
23
|
+
@success ||= success_response? && @original&.success?
|
24
|
+
end
|
25
|
+
|
26
|
+
def code
|
27
|
+
return if timeout?
|
28
|
+
|
29
|
+
@code ||= success_response? ? @original.status : @original.response[:status]
|
30
|
+
end
|
31
|
+
|
32
|
+
def timeout?
|
33
|
+
@original.is_a?(Faraday::TimeoutError) ||
|
34
|
+
@original.is_a?(Net::ReadTimeout) ||
|
35
|
+
@original.is_a?(Faraday::ConnectionFailed)
|
36
|
+
end
|
37
|
+
|
38
|
+
def log
|
39
|
+
Eezee::Logger.response(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def parsed_body
|
45
|
+
JSON.parse(handled_faraday_response, symbolize_names: true)
|
46
|
+
end
|
47
|
+
|
48
|
+
def success_response?
|
49
|
+
@original.is_a?(Faraday::Response)
|
50
|
+
end
|
51
|
+
|
52
|
+
def handled_faraday_response
|
53
|
+
faraday_response.nil? || faraday_response.empty? ? '{}' : faraday_response
|
54
|
+
end
|
55
|
+
|
56
|
+
def faraday_response
|
57
|
+
success_response? ? @original.body : @original.response[:body]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/eezee.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eezee/version'
|
4
|
+
require 'eezee/errors'
|
5
|
+
require 'eezee/request'
|
6
|
+
require 'eezee/response'
|
7
|
+
require 'eezee/request_error_factory'
|
8
|
+
require 'eezee/logger'
|
9
|
+
require 'eezee/configuration'
|
10
|
+
require 'eezee/client'
|
11
|
+
|
12
|
+
module Eezee
|
13
|
+
class << self
|
14
|
+
def configure
|
15
|
+
yield(configuration)
|
16
|
+
end
|
17
|
+
|
18
|
+
def configuration
|
19
|
+
@configuration ||= Configuration.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators/base'
|
4
|
+
|
5
|
+
module Eezee
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
def create_initializer_file
|
8
|
+
create_file(
|
9
|
+
'config/initializers/eezee.rb',
|
10
|
+
<<~KATINGUELE_INITIALIZER_TEXT
|
11
|
+
# frozen_string_literal: true
|
12
|
+
|
13
|
+
Eezee.configure do |config|
|
14
|
+
# You can add your service's configuration, like:
|
15
|
+
|
16
|
+
# config.add_service :external_service_1,
|
17
|
+
# raise_error: true,
|
18
|
+
# url: ENV['EXTERNAL_SERVICE_URL_1'],
|
19
|
+
# headers: { 'Content-Type' => 'application/json' }
|
20
|
+
|
21
|
+
# config.add_service :external_service_2,
|
22
|
+
# raise_error: false,
|
23
|
+
# url: ENV['EXTERNAL_SERVICE_URL_2'],
|
24
|
+
# headers: { 'Token' => "#Token {ENV['EXTERNAL_SERVICE_TOKEN']}"}
|
25
|
+
|
26
|
+
# All available options is on README
|
27
|
+
end
|
28
|
+
KATINGUELE_INITIALIZER_TEXT
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eezee
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- linqueta
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.17.0
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.17'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.17.0
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.17'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: factory_bot
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.1'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 5.1.1
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '5.1'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 5.1.1
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: pry-byebug
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 3.7.0
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '3.7'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 3.7.0
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '3.7'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rake
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '10.0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '10.0'
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: rspec
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '3.0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '3.0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: rubocop
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 0.74.0
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.74'
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.74.0
|
132
|
+
- - "~>"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0.74'
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: rubocop-performance
|
137
|
+
requirement: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - "~>"
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '1.4'
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 1.4.1
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '1.4'
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 1.4.1
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: simplecov
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 0.17.0
|
162
|
+
- - "~>"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0.17'
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: 0.17.0
|
172
|
+
- - "~>"
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0.17'
|
175
|
+
- !ruby/object:Gem::Dependency
|
176
|
+
name: simplecov-console
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: 0.5.0
|
182
|
+
- - "~>"
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0.5'
|
185
|
+
type: :development
|
186
|
+
prerelease: false
|
187
|
+
version_requirements: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 0.5.0
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0.5'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: vcr
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 5.0.0
|
202
|
+
- - "~>"
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '5.0'
|
205
|
+
type: :development
|
206
|
+
prerelease: false
|
207
|
+
version_requirements: !ruby/object:Gem::Requirement
|
208
|
+
requirements:
|
209
|
+
- - ">="
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: 5.0.0
|
212
|
+
- - "~>"
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '5.0'
|
215
|
+
- !ruby/object:Gem::Dependency
|
216
|
+
name: webmock
|
217
|
+
requirement: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - "~>"
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '3.7'
|
222
|
+
- - ">="
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: 3.7.6
|
225
|
+
type: :development
|
226
|
+
prerelease: false
|
227
|
+
version_requirements: !ruby/object:Gem::Requirement
|
228
|
+
requirements:
|
229
|
+
- - "~>"
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: '3.7'
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: 3.7.6
|
235
|
+
description: A library to execute HTTP request in an easy way
|
236
|
+
email:
|
237
|
+
- lincolnrodrs@gmail.com
|
238
|
+
executables: []
|
239
|
+
extensions: []
|
240
|
+
extra_rdoc_files: []
|
241
|
+
files:
|
242
|
+
- MIT-LICENSE
|
243
|
+
- README.md
|
244
|
+
- lib/eezee.rb
|
245
|
+
- lib/eezee/client.rb
|
246
|
+
- lib/eezee/client/builder.rb
|
247
|
+
- lib/eezee/client/requester.rb
|
248
|
+
- lib/eezee/configuration.rb
|
249
|
+
- lib/eezee/errors.rb
|
250
|
+
- lib/eezee/errors/error.rb
|
251
|
+
- lib/eezee/errors/request_error.rb
|
252
|
+
- lib/eezee/errors/required_field_error.rb
|
253
|
+
- lib/eezee/errors/timeout_error.rb
|
254
|
+
- lib/eezee/logger.rb
|
255
|
+
- lib/eezee/request.rb
|
256
|
+
- lib/eezee/request_error_factory.rb
|
257
|
+
- lib/eezee/response.rb
|
258
|
+
- lib/eezee/version.rb
|
259
|
+
- lib/generators/katinguele/install_generator.rb
|
260
|
+
homepage: https://github.com/linqueta/eezee
|
261
|
+
licenses:
|
262
|
+
- MIT
|
263
|
+
metadata: {}
|
264
|
+
post_install_message:
|
265
|
+
rdoc_options: []
|
266
|
+
require_paths:
|
267
|
+
- lib
|
268
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
269
|
+
requirements:
|
270
|
+
- - ">="
|
271
|
+
- !ruby/object:Gem::Version
|
272
|
+
version: '0'
|
273
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
274
|
+
requirements:
|
275
|
+
- - ">="
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: '0'
|
278
|
+
requirements: []
|
279
|
+
rubygems_version: 3.0.3
|
280
|
+
signing_key:
|
281
|
+
specification_version: 4
|
282
|
+
summary: The easiest HTTP client for Ruby
|
283
|
+
test_files: []
|