rom-http 0.7.0 → 0.8.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 +5 -5
- data/CHANGELOG.md +26 -2
- data/LICENSE.txt +1 -1
- data/README.md +12 -15
- data/lib/rom-http.rb +2 -0
- data/lib/rom/http.rb +2 -0
- data/lib/rom/http/attribute.rb +10 -0
- data/lib/rom/http/commands.rb +2 -0
- data/lib/rom/http/commands/create.rb +2 -0
- data/lib/rom/http/commands/delete.rb +2 -0
- data/lib/rom/http/commands/update.rb +2 -0
- data/lib/rom/http/dataset.rb +152 -101
- data/lib/rom/http/error.rb +2 -0
- data/lib/rom/http/gateway.rb +44 -3
- data/lib/rom/http/handlers.rb +14 -0
- data/lib/rom/http/handlers/json.rb +65 -0
- data/lib/rom/http/mapper_compiler.rb +11 -0
- data/lib/rom/http/relation.rb +19 -64
- data/lib/rom/http/schema.rb +20 -0
- data/lib/rom/http/schema/dsl.rb +12 -0
- data/lib/rom/http/transformer.rb +2 -0
- data/lib/rom/http/types.rb +13 -0
- data/lib/rom/http/version.rb +3 -1
- metadata +32 -59
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.rubocop.yml +0 -22
- data/.rubocop_todo.yml +0 -12
- data/.travis.yml +0 -20
- data/Gemfile +0 -24
- data/Rakefile +0 -24
- data/examples/repository_with_combine.rb +0 -154
- data/lib/rom/http/dataset/class_interface.rb +0 -33
- data/rakelib/rubocop.rake +0 -18
- data/rom-http.gemspec +0 -32
- data/spec/integration/abstract/commands/create_spec.rb +0 -119
- data/spec/integration/abstract/commands/delete_spec.rb +0 -52
- data/spec/integration/abstract/commands/update_spec.rb +0 -119
- data/spec/integration/abstract/relation_spec.rb +0 -78
- data/spec/shared/setup.rb +0 -18
- data/spec/shared/users_and_tasks.rb +0 -30
- data/spec/spec_helper.rb +0 -19
- data/spec/support/mutant.rb +0 -10
- data/spec/unit/rom/http/dataset_spec.rb +0 -824
- data/spec/unit/rom/http/gateway_spec.rb +0 -69
- data/spec/unit/rom/http/relation_spec.rb +0 -268
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d88086baa2e0dccb6c7917f2e0a5ccf3ec268fa722f1648283b66ea9feb839e2
|
4
|
+
data.tar.gz: 3c4385179232ad49adc12214a00ecd690663828eaf1defb05d7af042a3e85d8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a9ff4446983f2b2a996e8ea488b2f8212a16aaaeac1165244169c6d914df3bb8decdc8eb7ecef4c5afec98c0f29162d923dd288146770de8f10b4ff5335ba32
|
7
|
+
data.tar.gz: e0078237b342b0578adad5a8741fa80ad2798d9d5038d30eb4eef329e440486e028f98084ffac936948e1bb94d27552c81ecca56a83b98ec67980598e8a2761f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
# v0.8.0 2019-04-29
|
2
|
+
|
3
|
+
This is a major overhaul of the gem which brings it closer to 1.0.0. Custom data mapping was replaced by core APIs that leverage schemas and their attributes. Custom `MapperCompiler` was added that rejects keys that are not specified in the schemas, and can be extended further to meet any future requirements.
|
4
|
+
|
5
|
+
As a consequence of these changes, with this release you can easily use `rom-http` along with repositories and changesets.
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Support for relation schemas (solnic)
|
10
|
+
- Support for auto-struct mapping (solnic)
|
11
|
+
- Support for registering your own request/response handlers for all datasets from a specific gateway (solnic)
|
12
|
+
- Built-in `JSON` handlers that you can set via `handlers: :json` gateway option (solnic)
|
13
|
+
- Convenient request method predicates `Dataset#{get?,post?,delete?,put?}` (solnic)
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- Updated to work with `rom ~> 5.0` (parndt)
|
18
|
+
- Input/output data are now handled by core functionality using schema's `input_schema` and `output_schema` (solnic)
|
19
|
+
- `Dataset#name` was removed in favor of `Dataset#base_path`
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
|
23
|
+
- `Relation#append_path` no longer duplicates `base_path` (solnic)
|
24
|
+
|
25
|
+
[Compare v0.7.0...v0.8.0](https://github.com/rom-rb/rom-http/compare/v0.7.0...v0.8.0)
|
26
|
+
|
1
27
|
# v0.7.0 2018-01-11
|
2
28
|
|
3
29
|
### Added
|
@@ -9,8 +35,6 @@
|
|
9
35
|
- Removed ruby 2.1 support (maximderbin)
|
10
36
|
- Removed rbx-3 support (maximderbin)
|
11
37
|
|
12
|
-
|
13
|
-
|
14
38
|
[Compare v0.5.0...v0.6.0](https://github.com/rom-rb/rom-http/compare/v0.6.0...v0.7.0)
|
15
39
|
|
16
40
|
# v0.6.0 2017-02-06
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
[gem]: https://rubygems.org/gems/rom-http
|
2
2
|
[travis]: https://travis-ci.org/rom-rb/rom-http
|
3
|
-
[gemnasium]: https://gemnasium.com/rom-rb/rom-http
|
4
3
|
[codeclimate]: https://codeclimate.com/github/rom-rb/rom-http
|
5
4
|
[inchpages]: http://inch-ci.org/github/rom-rb/rom-http
|
6
|
-
[
|
7
|
-
[rom]: https://github.com/rom-rb/rom
|
5
|
+
[chat]: https://rom-rb.zulipchat.com
|
8
6
|
|
9
|
-
|
10
|
-
# rom-http [][gitter]
|
7
|
+
# rom-http [][chat]
|
11
8
|
|
12
9
|
[][gem]
|
13
10
|
[][travis]
|
14
|
-
[][gemnasium]
|
15
11
|
[][codeclimate]
|
16
|
-
[][codeclimate]
|
13
|
+
[][inchpages]
|
14
|
+
|
15
|
+
HTTP adapter for [rom-rb](https://github.com/rom-rb/rom).
|
16
|
+
|
17
|
+
Resources:
|
17
18
|
|
18
|
-
|
19
|
+
- [User Documentation](http://rom-rb.org/learn/http/)
|
20
|
+
- [API Documentation](http://rubydoc.info/gems/rom-http)
|
19
21
|
|
20
22
|
## Installation
|
21
23
|
|
@@ -33,11 +35,6 @@ Or install it yourself as:
|
|
33
35
|
|
34
36
|
$ gem install rom-http
|
35
37
|
|
36
|
-
## ROADMAP
|
37
|
-
|
38
|
-
For details please refer to [issues](https://github.com/rom-rb/rom-http/issues).
|
39
|
-
|
40
|
-
|
41
38
|
## License
|
42
39
|
|
43
40
|
See `LICENSE` file.
|
@@ -77,7 +74,7 @@ end
|
|
77
74
|
|
78
75
|
class Users < ROM::Relation[:http]
|
79
76
|
schema(:users) do
|
80
|
-
attribute :id, ROM::Types::
|
77
|
+
attribute :id, ROM::Types::Integer
|
81
78
|
attribute :name, ROM::Types::String
|
82
79
|
attribute :username, ROM::Types::String
|
83
80
|
attribute :email, ROM::Types::String
|
@@ -174,7 +171,7 @@ configuration = ROM::Configuration.new(:my_adapter, {
|
|
174
171
|
|
175
172
|
class Users < ROM::Relation[:my_adapter]
|
176
173
|
schema(:users) do
|
177
|
-
attribute :id, ROM::Types::
|
174
|
+
attribute :id, ROM::Types::Integer
|
178
175
|
attribute :name, ROM::Types::String
|
179
176
|
attribute :username, ROM::Types::String
|
180
177
|
attribute :email, ROM::Types::String
|
data/lib/rom-http.rb
CHANGED
data/lib/rom/http.rb
CHANGED
data/lib/rom/http/commands.rb
CHANGED
data/lib/rom/http/dataset.rb
CHANGED
@@ -1,114 +1,194 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'uri'
|
2
|
-
|
4
|
+
|
5
|
+
require 'dry/configurable'
|
3
6
|
require 'dry/core/deprecations'
|
7
|
+
|
8
|
+
require 'rom/support/memoizable'
|
9
|
+
require 'rom/constants'
|
4
10
|
require 'rom/initializer'
|
5
|
-
require 'rom/http/
|
11
|
+
require 'rom/http/types'
|
12
|
+
require 'rom/http/transformer'
|
6
13
|
|
7
14
|
module ROM
|
8
15
|
module HTTP
|
9
16
|
# HTTP Dataset
|
10
17
|
#
|
11
|
-
# Represents a specific HTTP collection resource
|
18
|
+
# Represents a specific HTTP collection resource. This class can be
|
19
|
+
# subclassed in a specialized HTTP adapter to provide its own
|
20
|
+
# response/request handlers or any other configuration that should
|
21
|
+
# differ from the defaults.
|
12
22
|
#
|
13
23
|
# @api public
|
14
24
|
class Dataset
|
15
25
|
PATH_SEPARATOR = '/'.freeze
|
16
26
|
|
17
|
-
extend ::
|
18
|
-
extend ::
|
19
|
-
|
20
|
-
include ::
|
21
|
-
include
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
#
|
27
|
+
extend Dry::Configurable
|
28
|
+
extend ROM::Initializer
|
29
|
+
|
30
|
+
include ROM::Memoizable
|
31
|
+
include Enumerable
|
32
|
+
include Dry::Equalizer(:options)
|
33
|
+
|
34
|
+
# @!method self.default_request_handler
|
35
|
+
# Return configured default request handler
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# class MyDataset < ROM::HTTP::Dataset
|
39
|
+
# configure do |config|
|
40
|
+
# config.default_request_handler = MyRequestHandler
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# MyDataset.default_request_handler # MyRequestHandler
|
45
|
+
# MyDataset.new(uri: "http://localhost").request_handler # MyRequestHandler
|
46
|
+
setting :default_request_handler, reader: true
|
47
|
+
|
48
|
+
# @!method self.default_response_handler
|
49
|
+
# Return configured default response handler
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# class MyDataset < ROM::HTTP::Dataset
|
53
|
+
# configure do |config|
|
54
|
+
# config.default_response_handler = MyResponseHandler
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# MyDataset.default_response_handler # MyResponseHandler
|
59
|
+
# MyDataset.new(uri: "http://localhost").response_handler # MyResponseHandler
|
60
|
+
setting :default_response_handler, reader: true
|
61
|
+
|
62
|
+
# @!method self.param_encoder
|
63
|
+
# Return configured param encoder
|
64
|
+
#
|
65
|
+
# @example
|
66
|
+
# class MyDataset < ROM::HTTP::Dataset
|
67
|
+
# configure do |config|
|
68
|
+
# config.param_encoder = MyParamEncoder
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# MyDataset.param_encoder # MyParamEncoder
|
73
|
+
# MyDataset.new(uri: "http://localhost").param_encoder # MyParamEncoder
|
74
|
+
setting :param_encoder, URI.method(:encode_www_form), reader: true
|
75
|
+
|
76
|
+
# @!attribute [r] request_handler
|
77
|
+
# @return [Object]
|
78
|
+
# @api public
|
79
|
+
option :request_handler, default: proc { self.class.default_request_handler }
|
80
|
+
|
81
|
+
# @!attribute [r] response_handler
|
82
|
+
# @return [Object]
|
83
|
+
# @api public
|
84
|
+
option :response_handler, default: proc { self.class.default_response_handler }
|
85
|
+
|
86
|
+
# @!attribute [r] request_method
|
87
|
+
# @return [Symbol]
|
88
|
+
# @api public
|
89
|
+
option :request_method, type: Types::Symbol, default: proc { :get }
|
90
|
+
|
91
|
+
# @!attribute [r] base_path
|
92
|
+
# @return [String]
|
93
|
+
# @api public
|
94
|
+
option :base_path, type: Types::Path, default: proc { EMPTY_STRING }
|
95
|
+
|
96
|
+
# @!attribute [r] path
|
97
|
+
# @return [String]
|
98
|
+
# @api public
|
99
|
+
option :path, type: Types::Path, default: proc { EMPTY_STRING }
|
100
|
+
|
101
|
+
# @!attribute [r] params
|
102
|
+
# @return [Hash]
|
103
|
+
# @api public
|
104
|
+
option :params, type: Types::Hash, default: proc { EMPTY_HASH }
|
105
|
+
|
106
|
+
# @!attribute [r] headers
|
107
|
+
# @return [Hash]
|
108
|
+
# @api public
|
109
|
+
option :headers, type: Types::Hash, default: proc { EMPTY_HASH }
|
110
|
+
|
111
|
+
# @!attribute [r] headers
|
112
|
+
# @return [Hash]
|
113
|
+
# @api public
|
114
|
+
option :param_encoder, default: proc { self.class.param_encoder }
|
115
|
+
|
116
|
+
# @!attribute [r] uri
|
117
|
+
# @return [String]
|
118
|
+
# @api public
|
119
|
+
option :uri, type: Types::String
|
120
|
+
|
121
|
+
# Return the dataset's URI
|
122
|
+
#
|
123
|
+
# @return [URI::HTTP]
|
40
124
|
#
|
41
125
|
# @api public
|
42
126
|
def uri
|
43
|
-
uri =
|
44
|
-
|
45
|
-
if
|
46
|
-
uri.query =
|
127
|
+
uri = URI(join_path(super, path))
|
128
|
+
|
129
|
+
if get? && params.any?
|
130
|
+
uri.query = param_encoder.call(params)
|
47
131
|
end
|
48
132
|
|
49
133
|
uri
|
50
134
|
end
|
51
135
|
|
52
|
-
# Return request
|
136
|
+
# Return true if request method is set to :get
|
53
137
|
#
|
54
|
-
#
|
55
|
-
# current Dataset
|
138
|
+
# @return [Boolean]
|
56
139
|
#
|
57
|
-
# @
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
140
|
+
# @api public
|
141
|
+
def get?
|
142
|
+
request_method.equal?(:get)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Return true if request method is set to :post
|
62
146
|
#
|
63
|
-
# @return [
|
147
|
+
# @return [Boolean]
|
64
148
|
#
|
65
149
|
# @api public
|
66
|
-
def
|
67
|
-
|
150
|
+
def post?
|
151
|
+
request_method.equal?(:post)
|
68
152
|
end
|
69
153
|
|
70
|
-
# Return
|
154
|
+
# Return true if request method is set to :put
|
71
155
|
#
|
72
|
-
# @return [
|
156
|
+
# @return [Boolean]
|
73
157
|
#
|
74
158
|
# @api public
|
75
|
-
def
|
76
|
-
|
159
|
+
def put?
|
160
|
+
request_method.equal?(:put)
|
77
161
|
end
|
78
162
|
|
79
|
-
# Return
|
80
|
-
#
|
81
|
-
# @example
|
82
|
-
# Dataset.new(config, base_path: '/users').base_path
|
83
|
-
# # => 'users'
|
163
|
+
# Return true if request method is set to :delete
|
84
164
|
#
|
85
|
-
# @return [
|
165
|
+
# @return [Boolean]
|
86
166
|
#
|
87
167
|
# @api public
|
88
|
-
def
|
89
|
-
|
168
|
+
def delete?
|
169
|
+
request_method.equal?(:delete)
|
90
170
|
end
|
91
171
|
|
92
172
|
# Return the dataset path
|
93
173
|
#
|
94
174
|
# @example
|
95
|
-
# Dataset.new(
|
175
|
+
# Dataset.new(path: '/users').path
|
96
176
|
# # => 'users'
|
97
177
|
#
|
98
178
|
# @return [String] the dataset path, without a leading slash
|
99
179
|
#
|
100
180
|
# @api public
|
101
181
|
def path
|
102
|
-
join_path(base_path,
|
182
|
+
join_path(base_path, super)
|
103
183
|
end
|
104
184
|
|
105
185
|
# Return the dataset path
|
106
186
|
#
|
107
187
|
# @example
|
108
|
-
# Dataset.new(
|
188
|
+
# Dataset.new(path: '/users').path
|
109
189
|
# # => '/users'
|
110
190
|
#
|
111
|
-
# @return [
|
191
|
+
# @return [String] the dataset path, with leading slash
|
112
192
|
#
|
113
193
|
# @api public
|
114
194
|
def absolute_path
|
@@ -123,7 +203,7 @@ module ROM
|
|
123
203
|
# To non-destructively add a new header, use `#add_header`
|
124
204
|
#
|
125
205
|
# @example
|
126
|
-
# users = Dataset.new(
|
206
|
+
# users = Dataset.new(headers: { Accept: 'application/json' })
|
127
207
|
# users.with_headers(:'X-Api-Key' => '1234').headers
|
128
208
|
# # => { :'X-Api-Key' => '1234' }
|
129
209
|
#
|
@@ -131,7 +211,7 @@ module ROM
|
|
131
211
|
#
|
132
212
|
# @api public
|
133
213
|
def with_headers(headers)
|
134
|
-
|
214
|
+
with_options(headers: headers)
|
135
215
|
end
|
136
216
|
|
137
217
|
# Return a new dataset with additional header
|
@@ -140,7 +220,7 @@ module ROM
|
|
140
220
|
# @param value [String] the header value
|
141
221
|
#
|
142
222
|
# @example
|
143
|
-
# users = Dataset.new(
|
223
|
+
# users = Dataset.new(headers: { Accept: 'application/json' })
|
144
224
|
# users.add_header(:'X-Api-Key', '1234').headers
|
145
225
|
# # => { :Accept => 'application/json', :'X-Api-Key' => '1234' }
|
146
226
|
#
|
@@ -159,7 +239,7 @@ module ROM
|
|
159
239
|
#
|
160
240
|
# @api public
|
161
241
|
def with_options(opts)
|
162
|
-
__new__(
|
242
|
+
__new__(options.merge(opts))
|
163
243
|
end
|
164
244
|
|
165
245
|
# Return a new dataset with a different base path
|
@@ -204,7 +284,7 @@ module ROM
|
|
204
284
|
#
|
205
285
|
# @api public
|
206
286
|
def append_path(append_path)
|
207
|
-
|
287
|
+
with_path(join_path(options[:path], append_path))
|
208
288
|
end
|
209
289
|
|
210
290
|
# Return a new dataset with a different request method
|
@@ -226,7 +306,7 @@ module ROM
|
|
226
306
|
# @param [Hash] params the new request parameters
|
227
307
|
#
|
228
308
|
# @example
|
229
|
-
# users = Dataset.new(
|
309
|
+
# users = Dataset.new(params: { uid: 33 })
|
230
310
|
# users.with_params(login: 'jdoe').params
|
231
311
|
# # => { :login => 'jdoe' }
|
232
312
|
#
|
@@ -242,7 +322,7 @@ module ROM
|
|
242
322
|
# @param [Hash] params the new request parameters to add
|
243
323
|
#
|
244
324
|
# @example
|
245
|
-
# users = Dataset.new(
|
325
|
+
# users = Dataset.new(params: { uid: 33 })
|
246
326
|
# users.add_params(login: 'jdoe').params
|
247
327
|
# # => { uid: 33, :login => 'jdoe' }
|
248
328
|
#
|
@@ -250,10 +330,7 @@ module ROM
|
|
250
330
|
#
|
251
331
|
# @api public
|
252
332
|
def add_params(new_params)
|
253
|
-
|
254
|
-
with_options(
|
255
|
-
params: ::ROM::HTTP::Transformer[:deep_merge][params, new_params]
|
256
|
-
)
|
333
|
+
with_options(params: ::ROM::HTTP::Transformer[:deep_merge][params, new_params])
|
257
334
|
end
|
258
335
|
|
259
336
|
# Iterate over each response value
|
@@ -277,10 +354,7 @@ module ROM
|
|
277
354
|
#
|
278
355
|
# @api public
|
279
356
|
def insert(params)
|
280
|
-
with_options(
|
281
|
-
request_method: :post,
|
282
|
-
params: params
|
283
|
-
).response
|
357
|
+
with_options(request_method: :post, params: params).response
|
284
358
|
end
|
285
359
|
|
286
360
|
# Perform an update over HTTP Put
|
@@ -291,10 +365,7 @@ module ROM
|
|
291
365
|
#
|
292
366
|
# @api public
|
293
367
|
def update(params)
|
294
|
-
with_options(
|
295
|
-
request_method: :put,
|
296
|
-
params: params
|
297
|
-
).response
|
368
|
+
with_options(request_method: :put, params: params).response
|
298
369
|
end
|
299
370
|
|
300
371
|
# Perform an delete over HTTP Delete
|
@@ -304,9 +375,7 @@ module ROM
|
|
304
375
|
#
|
305
376
|
# @api public
|
306
377
|
def delete
|
307
|
-
with_options(
|
308
|
-
request_method: :delete
|
309
|
-
).response
|
378
|
+
with_options(request_method: :delete).response
|
310
379
|
end
|
311
380
|
|
312
381
|
# Execute the current dataset
|
@@ -318,37 +387,19 @@ module ROM
|
|
318
387
|
response_handler.call(request_handler.call(self), self)
|
319
388
|
end
|
320
389
|
|
321
|
-
|
322
|
-
|
323
|
-
def response_handler
|
324
|
-
response_handler = config.fetch(
|
325
|
-
:response_handler,
|
326
|
-
self.class.config.default_response_handler
|
327
|
-
)
|
328
|
-
fail Error, '+default_response_handler+ configuration missing' if response_handler.nil?
|
329
|
-
response_handler
|
330
|
-
end
|
390
|
+
memoize :uri, :absolute_path
|
331
391
|
|
332
|
-
|
333
|
-
request_handler = config.fetch(
|
334
|
-
:request_handler,
|
335
|
-
self.class.config.default_request_handler
|
336
|
-
)
|
337
|
-
fail Error, '+default_response_handler+ configuration missing' if request_handler.nil?
|
338
|
-
request_handler
|
339
|
-
end
|
392
|
+
private
|
340
393
|
|
394
|
+
# @api private
|
341
395
|
def __new__(*args, &block)
|
342
396
|
self.class.new(*args, &block)
|
343
397
|
end
|
344
398
|
|
399
|
+
# @api private
|
345
400
|
def join_path(*paths)
|
346
401
|
paths.reject(&:empty?).join(PATH_SEPARATOR)
|
347
402
|
end
|
348
|
-
|
349
|
-
def strip_path(path)
|
350
|
-
path.sub(%r{\A/}, '')
|
351
|
-
end
|
352
403
|
end
|
353
404
|
end
|
354
405
|
end
|