rest_api_builder 0.0.1 → 0.0.6
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 +4 -4
- data/LICENSE +0 -0
- data/README.md +30 -1
- data/lib/rest_api_builder.rb +20 -0
- data/lib/rest_api_builder/request.rb +17 -23
- data/lib/rest_api_builder/request_options.rb +33 -0
- data/lib/rest_api_builder/response_handler.rb +44 -0
- data/lib/rest_api_builder/url_helper.rb +0 -0
- data/lib/rest_api_builder/webmock_request_expectations.rb +15 -2
- data/rest_api_builder.gemspec +1 -1
- metadata +6 -4
- data/lib/rest_api_builder/rest_client_response_parser.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e04eb4a2a88c29a02d4fc831018d118ce8cd570f7523625cc83bd155041734a
|
4
|
+
data.tar.gz: 1092c81256426cb4d0e590452c0831291b20697108a07358fe5efdc5761d74b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b494a395a84ce64096cbe07231457e742de4ddd812bdf092e00e717db0c078496c907d81d19e671f32ce484f8b6464e310aba16184c6ed4724d0c0c19f7a5749
|
7
|
+
data.tar.gz: 2626417df9c9241d33ac3e76b2a9a5f64638b6a0397785c470f921303fb47188ab606914fc4890b47aaf4fd4fdc6f96fe8c6569ac9a29f114b9854ef66d48c29
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -84,7 +84,7 @@ response[:status] #=> 200
|
|
84
84
|
response[:body] #=> ''
|
85
85
|
response[:headers] #=> {}
|
86
86
|
|
87
|
-
# Specifying
|
87
|
+
# Specifying expectation details with WebMock::Request methods
|
88
88
|
Expectations
|
89
89
|
.expect_execute(base_url: "test.com", method: :get)
|
90
90
|
.to_return(status: 404, body: "not found")
|
@@ -93,6 +93,29 @@ response = Request.execute(base_url: "test.com", method: :get)
|
|
93
93
|
response[:success] #=> false
|
94
94
|
response[:status] #=> 404
|
95
95
|
response[:body] #=> "not found"
|
96
|
+
|
97
|
+
# Specifying expectation details with :request and :response options
|
98
|
+
Expectations.expect_execute(
|
99
|
+
base_url: "test.com",
|
100
|
+
method: :post,
|
101
|
+
response: { body: 'hello' },
|
102
|
+
request: { body: WebMock::API.hash_including({foo: "bar"}) }
|
103
|
+
)
|
104
|
+
response = Request.json_execute(base_url: "test.com", method: :post, body: {foo: "bar"})
|
105
|
+
response[:success] #=> true
|
106
|
+
response[:body] #=> 'hello'
|
107
|
+
|
108
|
+
Request.json_execute(base_url: "test.com", method: :post, body: {bar: "baz"}) # => Raises WebMock::NetConnectNotAllowedError
|
109
|
+
|
110
|
+
# Using #expect_json_execute
|
111
|
+
Expectations.expect_json_execute(
|
112
|
+
base_url: "test.com",
|
113
|
+
method: :get,
|
114
|
+
response: { body: {hi: 'hello'} }
|
115
|
+
)
|
116
|
+
response = Request.execute(base_url: "test.com", method: :get)
|
117
|
+
response[:success] #=> true
|
118
|
+
response[:body] #=> "{\"hi\":\"hello\"}"
|
96
119
|
```
|
97
120
|
|
98
121
|
## Request API
|
@@ -110,6 +133,7 @@ Does not throw on non-200 responses like RestClient does, but will throw on any
|
|
110
133
|
* **query**: Query hash to be appended to the resulting url. Optional.
|
111
134
|
* **logger**: A `Logger` instance to be passed to RestClient in `log` option. Will also log response details as RestClient does not do this by default. Optional
|
112
135
|
* **parse_json**: Boolean. If `true`, will attempt to parse the response body as JSON. Will return the response body unchanged if it does not contain valid JSON. `false` by default.
|
136
|
+
* **raw_response**: Boolean. If `true`, the response returned by RestClient will not be parsed into {:status, :body, :headers}, but instead returned as {:raw_response}. `false` by default.
|
113
137
|
* **rest_client_options**: Any additional options to be passed to `RestClient::Request.execute` unchanged. **Any option set here will completely overwrite all custom options**. For example, if you call `RestAPIBuilder::Request.execute(method: :post, rest_client_options: {method: :get})`, the resulting request will be sent as GET. Optional.
|
114
138
|
|
115
139
|
### RestAPIBuilder::Request.json_execute(options)
|
@@ -127,6 +151,11 @@ Defines a request expectation using WebMock's `stub_request`. Returns an instanc
|
|
127
151
|
* **base_url**: Base URL of the request. Required.
|
128
152
|
* **method**: HTTP method of the request(e.g :get, :post, :patch). Required.
|
129
153
|
* **path**: Path to be appended to the :base_url. Optional.
|
154
|
+
* **request**: request details which will be passed to `WebMock::RequestStub#with` if provided. Optional
|
155
|
+
* **response**: response details which will be passed to `WebMock::RequestStub#to_return` if provided. Optional
|
156
|
+
|
157
|
+
### RestAPIBuilder::WebMockRequestExpectations.expect_json_execute(options)
|
158
|
+
A convenience shortcut for `#json_execute` which will convert `request[:body]` to JSON if it's provided
|
130
159
|
|
131
160
|
## License
|
132
161
|
MIT
|
data/lib/rest_api_builder.rb
CHANGED
@@ -1 +1,21 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
require 'rest_api_builder/request'
|
3
|
+
require 'rest_api_builder/request_options'
|
4
|
+
require 'rest_api_builder/response_handler'
|
5
|
+
|
6
|
+
module RestAPIBuilder
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegator :request_options, :compose, :compose_request_options
|
10
|
+
def_delegator :request_options, :compose_json, :compose_json_request_options
|
11
|
+
|
12
|
+
def_delegators :response_handler, :handle_response, :handle_json_response, :handle_response_error
|
13
|
+
|
14
|
+
def request_options
|
15
|
+
RequestOptions.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def response_handler
|
19
|
+
ResponseHandler.new
|
20
|
+
end
|
21
|
+
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'rest-client'
|
2
|
-
require 'rest_api_builder/url_helper'
|
3
|
-
require 'rest_api_builder/rest_client_response_parser'
|
4
2
|
|
5
3
|
module RestAPIBuilder
|
6
4
|
class RequestSingleton
|
7
|
-
include RestAPIBuilder::UrlHelper
|
8
|
-
|
9
5
|
def json_execute(headers: {}, body: nil, **options)
|
10
6
|
headers = headers.merge(content_type: :json)
|
11
7
|
body &&= JSON.generate(body)
|
@@ -21,29 +17,27 @@ module RestAPIBuilder
|
|
21
17
|
path: nil,
|
22
18
|
logger: nil,
|
23
19
|
parse_json: false,
|
20
|
+
raw_response: false,
|
24
21
|
rest_client_options: {}
|
25
22
|
)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
options = RequestOptions.new.compose(
|
24
|
+
base_url: base_url,
|
25
|
+
method: method,
|
26
|
+
body: body,
|
27
|
+
headers: headers,
|
28
|
+
query: query,
|
29
|
+
path: path
|
30
|
+
)
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
method: method,
|
36
|
-
url: full_url(base_url, path),
|
37
|
-
payload: body,
|
38
|
-
headers: headers,
|
39
|
-
log: logger,
|
40
|
-
**rest_client_options
|
41
|
-
)
|
42
|
-
response_parser.parse_response(response, success: true)
|
43
|
-
rescue RestClient::RequestFailed => e
|
44
|
-
raise e unless e.response
|
32
|
+
response_handler = ResponseHandler.new
|
33
|
+
execute_request = proc { RestClient::Request.execute(**options, log: logger, **rest_client_options) }
|
45
34
|
|
46
|
-
|
35
|
+
if raw_response
|
36
|
+
response_handler.handle_response_error(&execute_request)
|
37
|
+
elsif parse_json
|
38
|
+
response_handler.handle_json_response(logger: logger, &execute_request)
|
39
|
+
else
|
40
|
+
response_handler.handle_response(logger: logger, &execute_request)
|
47
41
|
end
|
48
42
|
end
|
49
43
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rest_api_builder/url_helper'
|
2
|
+
|
3
|
+
module RestAPIBuilder
|
4
|
+
class RequestOptions
|
5
|
+
include RestAPIBuilder::UrlHelper
|
6
|
+
|
7
|
+
def compose(base_url:, method:, path: nil, body: nil, headers: {}, query: nil)
|
8
|
+
if method == :get && body
|
9
|
+
raise ArgumentError, 'GET requests do not support body'
|
10
|
+
end
|
11
|
+
|
12
|
+
headers = headers.merge(params: query) if query
|
13
|
+
|
14
|
+
{
|
15
|
+
method: method,
|
16
|
+
url: full_url(base_url, path),
|
17
|
+
payload: body,
|
18
|
+
headers: headers
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def compose_json(**options)
|
23
|
+
result = compose(**options)
|
24
|
+
headers = result[:headers]
|
25
|
+
payload = result[:payload]
|
26
|
+
|
27
|
+
result.merge(
|
28
|
+
headers: headers.merge(content_type: :json),
|
29
|
+
payload: payload && JSON.generate(payload)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RestAPIBuilder
|
2
|
+
class ResponseHandler
|
3
|
+
def handle_json_response(**options, &block)
|
4
|
+
result = handle_response(**options, &block)
|
5
|
+
result.merge(body: parse_json(result[:body]))
|
6
|
+
end
|
7
|
+
|
8
|
+
def handle_response(logger: nil, &block)
|
9
|
+
result = parse_response(**handle_response_error(&block))
|
10
|
+
maybe_log_result(result, logger: logger)
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle_response_error
|
15
|
+
response = yield
|
16
|
+
{ raw_response: response, success: true }
|
17
|
+
rescue RestClient::RequestFailed => e
|
18
|
+
raise e unless e.response
|
19
|
+
|
20
|
+
{ raw_response: e.response, success: false }
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse_response(raw_response:, success:)
|
26
|
+
{
|
27
|
+
success: success,
|
28
|
+
status: raw_response.code,
|
29
|
+
body: raw_response.body,
|
30
|
+
headers: raw_response.headers
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def maybe_log_result(result, logger:)
|
35
|
+
logger && logger << "# => Response: #{result}\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_json(json)
|
39
|
+
JSON.parse(json)
|
40
|
+
rescue JSON::ParserError
|
41
|
+
json
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
File without changes
|
@@ -6,8 +6,21 @@ module RestAPIBuilder
|
|
6
6
|
include WebMock::API
|
7
7
|
include RestAPIBuilder::UrlHelper
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def expect_json_execute(response: nil, **options)
|
10
|
+
if response && response[:body]
|
11
|
+
response = response.merge(body: JSON.generate(response[:body]))
|
12
|
+
end
|
13
|
+
|
14
|
+
expect_execute(**options, response: response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def expect_execute(base_url:, method:, path: nil, request: nil, response: nil)
|
18
|
+
expectation = stub_request(method, full_url(base_url, path))
|
19
|
+
|
20
|
+
expectation.with(request) if request
|
21
|
+
expectation.to_return(response) if response
|
22
|
+
|
23
|
+
expectation
|
11
24
|
end
|
12
25
|
end
|
13
26
|
|
data/rest_api_builder.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rest_api_builder'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.6'
|
4
4
|
s.summary = "A simple wrapper for rest-client"
|
5
5
|
s.description = "A simple wrapper for rest-client aiming to make creation and testing of API clients easier."
|
6
6
|
s.authors = ["Alexey D"]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest_api_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey D
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -63,7 +63,8 @@ files:
|
|
63
63
|
- README.md
|
64
64
|
- lib/rest_api_builder.rb
|
65
65
|
- lib/rest_api_builder/request.rb
|
66
|
-
- lib/rest_api_builder/
|
66
|
+
- lib/rest_api_builder/request_options.rb
|
67
|
+
- lib/rest_api_builder/response_handler.rb
|
67
68
|
- lib/rest_api_builder/url_helper.rb
|
68
69
|
- lib/rest_api_builder/webmock_request_expectations.rb
|
69
70
|
- rest_api_builder.gemspec
|
@@ -86,7 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
87
|
- !ruby/object:Gem::Version
|
87
88
|
version: '0'
|
88
89
|
requirements: []
|
89
|
-
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.7.8
|
90
92
|
signing_key:
|
91
93
|
specification_version: 4
|
92
94
|
summary: A simple wrapper for rest-client
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module RestAPIBuilder
|
4
|
-
class RestClientResponseParser
|
5
|
-
def initialize(logger:, parse_json:)
|
6
|
-
@logger = logger
|
7
|
-
@parse_json = parse_json
|
8
|
-
end
|
9
|
-
|
10
|
-
def parse_response(response, success:)
|
11
|
-
body = @parse_json ? parse_json(response.body) : response.body
|
12
|
-
result = {
|
13
|
-
success: success,
|
14
|
-
status: response.code,
|
15
|
-
body: body,
|
16
|
-
headers: response.headers
|
17
|
-
}
|
18
|
-
maybe_log_result(result)
|
19
|
-
|
20
|
-
result
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def parse_json(json)
|
26
|
-
JSON.parse(json)
|
27
|
-
rescue JSON::ParserError
|
28
|
-
json
|
29
|
-
end
|
30
|
-
|
31
|
-
def maybe_log_result(result)
|
32
|
-
@logger && @logger << "# => Response: #{result}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|