rom-http 0.7.0 → 0.9.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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +81 -28
  3. data/README.md +15 -181
  4. data/lib/rom/http/associations/many_to_many.rb +12 -0
  5. data/lib/rom/http/associations/many_to_one.rb +20 -0
  6. data/lib/rom/http/associations/one_to_many.rb +20 -0
  7. data/lib/rom/http/associations/one_to_one.rb +12 -0
  8. data/lib/rom/http/associations.rb +14 -0
  9. data/lib/rom/http/attribute.rb +10 -0
  10. data/lib/rom/http/commands/create.rb +2 -0
  11. data/lib/rom/http/commands/delete.rb +2 -0
  12. data/lib/rom/http/commands/update.rb +2 -0
  13. data/lib/rom/http/commands.rb +6 -4
  14. data/lib/rom/http/dataset.rb +212 -115
  15. data/lib/rom/http/error.rb +2 -0
  16. data/lib/rom/http/gateway.rb +47 -6
  17. data/lib/rom/http/handlers/json.rb +64 -0
  18. data/lib/rom/http/handlers.rb +16 -0
  19. data/lib/rom/http/mapper_compiler.rb +11 -0
  20. data/lib/rom/http/relation.rb +22 -66
  21. data/lib/rom/http/schema/dsl.rb +12 -0
  22. data/lib/rom/http/schema.rb +40 -0
  23. data/lib/rom/http/transformer.rb +2 -0
  24. data/lib/rom/http/types.rb +13 -0
  25. data/lib/rom/http/version.rb +3 -1
  26. data/lib/rom/http.rb +9 -6
  27. data/lib/rom-http.rb +3 -1
  28. metadata +41 -120
  29. data/.gitignore +0 -16
  30. data/.rspec +0 -3
  31. data/.rubocop.yml +0 -22
  32. data/.rubocop_todo.yml +0 -12
  33. data/.travis.yml +0 -20
  34. data/Gemfile +0 -24
  35. data/LICENSE.txt +0 -22
  36. data/Rakefile +0 -24
  37. data/examples/repository_with_combine.rb +0 -154
  38. data/lib/rom/http/dataset/class_interface.rb +0 -33
  39. data/rakelib/rubocop.rake +0 -18
  40. data/rom-http.gemspec +0 -32
  41. data/spec/integration/abstract/commands/create_spec.rb +0 -119
  42. data/spec/integration/abstract/commands/delete_spec.rb +0 -52
  43. data/spec/integration/abstract/commands/update_spec.rb +0 -119
  44. data/spec/integration/abstract/relation_spec.rb +0 -78
  45. data/spec/shared/setup.rb +0 -18
  46. data/spec/shared/users_and_tasks.rb +0 -30
  47. data/spec/spec_helper.rb +0 -19
  48. data/spec/support/mutant.rb +0 -10
  49. data/spec/unit/rom/http/dataset_spec.rb +0 -824
  50. data/spec/unit/rom/http/gateway_spec.rb +0 -69
  51. data/spec/unit/rom/http/relation_spec.rb +0 -268
@@ -1,114 +1,199 @@
1
- require 'uri'
2
- require 'dry-configurable'
3
- require 'dry/core/deprecations'
4
- require 'rom/initializer'
5
- require 'rom/http/dataset/class_interface'
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ require "dry/configurable"
6
+ require "dry/core/deprecations"
7
+
8
+ require "rom/support/memoizable"
9
+ require "rom/constants"
10
+ require "rom/initializer"
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
- PATH_SEPARATOR = '/'.freeze
16
-
17
- extend ::ROM::Initializer
18
- extend ::Dry::Configurable
19
- extend ::ROM::HTTP::Dataset::ClassInterface
20
- include ::Enumerable
21
- include ::Dry::Equalizer(:config, :options)
22
-
23
- setting :default_request_handler
24
- setting :default_response_handler
25
- setting :param_encoder, ->(params) { URI.encode_www_form(params) }
26
-
27
- param :config
28
-
29
- option :request_method, type: Types::Symbol, default: proc { :get }, reader: true
30
- option :base_path, type: Types::String, default: proc { name }
31
- option :path, type: Types::String, default: proc { '' }, reader: false
32
- option :params, type: Types::Hash, default: proc { {} }, reader: true
33
- option :headers, type: Types::Hash, default: proc { {} }
34
-
35
- # Return the gateway's URI
36
- #
37
- # @return [String]
38
- #
39
- # @raise [Error] if the configuration does not contain a URI
25
+ PATH_SEPARATOR = "/"
26
+
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.query_param_encoder
63
+ # Return configured query param encoder
64
+ #
65
+ # @example
66
+ # class MyDataset < ROM::HTTP::Dataset
67
+ # configure do |config|
68
+ # config.query_param_encoder = MyParamEncoder
69
+ # end
70
+ # end
71
+ #
72
+ # MyDataset.query_param_encoder # MyParamEncoder
73
+ # MyDataset.new(uri: "http://localhost").query_param_encoder # MyParamEncoder
74
+ setting :query_param_encoder, default: 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] query_params
102
+ # @return [Hash]
103
+ # @api public
104
+ option :query_params, type: Types::Hash, default: proc { EMPTY_HASH }
105
+
106
+ # @!attribute [r] body_params
107
+ # @return [Hash]
108
+ # @api public
109
+ option :body_params, type: Types::Hash, default: proc { EMPTY_HASH }
110
+
111
+ # @!attribute [r] headers
112
+ # @return [Hash]
113
+ # @api public
114
+ option :headers, type: Types::Hash, default: proc { EMPTY_HASH }
115
+
116
+ # @!attribute [r] headers
117
+ # @return [Hash]
118
+ # @api public
119
+ option :query_param_encoder, default: proc { self.class.query_param_encoder }
120
+
121
+ # @!attribute [r] uri
122
+ # @return [String]
123
+ # @api public
124
+ option :uri, type: Types::String
125
+
126
+ # Return the dataset's URI
127
+ #
128
+ # @return [URI::HTTP]
40
129
  #
41
130
  # @api public
42
131
  def uri
43
- uri = config.fetch(:uri) { fail Error, '+uri+ configuration missing' }
44
- uri = URI(join_path(uri, path))
45
- if request_method == :get && params.any?
46
- uri.query = self.class.config.param_encoder.call(params)
132
+ uri = URI(join_path(super, path))
133
+
134
+ if query_params.any?
135
+ uri.query = query_param_encoder.call(query_params)
47
136
  end
48
137
 
49
138
  uri
50
139
  end
51
140
 
52
- # Return request headers
141
+ # Return true if request method is set to :get
53
142
  #
54
- # Merges default headers from the Gateway configuration and the
55
- # current Dataset
143
+ # @return [Boolean]
56
144
  #
57
- # @example
58
- # config = { Accepts: 'application/json' }
59
- # users = Dataset.new(config, headers: { 'Cache-Control': 'no-cache' }
60
- # users.headers
61
- # # => {:Accepts => "application/json", :'Cache-Control' => 'no-cache'}
145
+ # @api public
146
+ def get?
147
+ request_method.equal?(:get)
148
+ end
149
+
150
+ # Return true if request method is set to :post
62
151
  #
63
- # @return [Hash]
152
+ # @return [Boolean]
64
153
  #
65
154
  # @api public
66
- def headers
67
- config.fetch(:headers, {}).merge(options.fetch(:headers, {}))
155
+ def post?
156
+ request_method.equal?(:post)
68
157
  end
69
158
 
70
- # Return the dataset name
159
+ # Return true if request method is set to :put
71
160
  #
72
- # @return [String]
161
+ # @return [Boolean]
73
162
  #
74
163
  # @api public
75
- def name
76
- config[:name].to_s
164
+ def put?
165
+ request_method.equal?(:put)
77
166
  end
78
167
 
79
- # Return the base path
80
- #
81
- # @example
82
- # Dataset.new(config, base_path: '/users').base_path
83
- # # => 'users'
168
+ # Return true if request method is set to :delete
84
169
  #
85
- # @return [String] the dataset path, without a leading slash
170
+ # @return [Boolean]
86
171
  #
87
172
  # @api public
88
- def base_path
89
- strip_path(super)
173
+ def delete?
174
+ request_method.equal?(:delete)
90
175
  end
91
176
 
92
177
  # Return the dataset path
93
178
  #
94
179
  # @example
95
- # Dataset.new(config, path: '/users').path
180
+ # Dataset.new(path: '/users').path
96
181
  # # => 'users'
97
182
  #
98
183
  # @return [String] the dataset path, without a leading slash
99
184
  #
100
185
  # @api public
101
186
  def path
102
- join_path(base_path, strip_path(options[:path].to_s))
187
+ join_path(base_path, super)
103
188
  end
104
189
 
105
190
  # Return the dataset path
106
191
  #
107
192
  # @example
108
- # Dataset.new(config, path: '/users').path
193
+ # Dataset.new(path: '/users').path
109
194
  # # => '/users'
110
195
  #
111
- # @return [string] the dataset path, with leading slash
196
+ # @return [String] the dataset path, with leading slash
112
197
  #
113
198
  # @api public
114
199
  def absolute_path
@@ -123,7 +208,7 @@ module ROM
123
208
  # To non-destructively add a new header, use `#add_header`
124
209
  #
125
210
  # @example
126
- # users = Dataset.new(config, headers: { Accept: 'application/json' })
211
+ # users = Dataset.new(headers: { Accept: 'application/json' })
127
212
  # users.with_headers(:'X-Api-Key' => '1234').headers
128
213
  # # => { :'X-Api-Key' => '1234' }
129
214
  #
@@ -131,7 +216,7 @@ module ROM
131
216
  #
132
217
  # @api public
133
218
  def with_headers(headers)
134
- __new__(config, options.merge(headers: headers))
219
+ with_options(headers: headers)
135
220
  end
136
221
 
137
222
  # Return a new dataset with additional header
@@ -140,7 +225,7 @@ module ROM
140
225
  # @param value [String] the header value
141
226
  #
142
227
  # @example
143
- # users = Dataset.new(config, headers: { Accept: 'application/json' })
228
+ # users = Dataset.new(headers: { Accept: 'application/json' })
144
229
  # users.add_header(:'X-Api-Key', '1234').headers
145
230
  # # => { :Accept => 'application/json', :'X-Api-Key' => '1234' }
146
231
  #
@@ -159,7 +244,7 @@ module ROM
159
244
  #
160
245
  # @api public
161
246
  def with_options(opts)
162
- __new__(config, options.merge(opts))
247
+ __new__(**options.merge(opts))
163
248
  end
164
249
 
165
250
  # Return a new dataset with a different base path
@@ -204,7 +289,7 @@ module ROM
204
289
  #
205
290
  # @api public
206
291
  def append_path(append_path)
207
- with_options(path: join_path(path, append_path))
292
+ with_path(join_path(options[:path], append_path))
208
293
  end
209
294
 
210
295
  # Return a new dataset with a different request method
@@ -221,39 +306,70 @@ module ROM
221
306
  with_options(request_method: request_method)
222
307
  end
223
308
 
224
- # Return a new dataset with replaced request parameters
309
+ # Return a new dataset with replaced request query parameters
225
310
  #
226
- # @param [Hash] params the new request parameters
311
+ # @param [Hash] query_params the new request query parameters
227
312
  #
228
313
  # @example
229
- # users = Dataset.new(config, params: { uid: 33 })
230
- # users.with_params(login: 'jdoe').params
314
+ # users = Dataset.new(query_params: { uid: 33 })
315
+ # users.with_query_params(login: 'jdoe').query_params
231
316
  # # => { :login => 'jdoe' }
232
317
  #
233
318
  # @return [Dataset]
234
319
  #
235
320
  # @api public
236
- def with_params(params)
237
- with_options(params: params)
321
+ def with_query_params(query_params)
322
+ with_options(query_params: query_params)
238
323
  end
239
324
 
240
- # Return a new dataset with merged request parameters
325
+ # Return a new dataset with merged request query parameters
241
326
  #
242
- # @param [Hash] params the new request parameters to add
327
+ # @param [Hash] query_params the new request query parameters to add
243
328
  #
244
329
  # @example
245
- # users = Dataset.new(config, params: { uid: 33 })
246
- # users.add_params(login: 'jdoe').params
330
+ # users = Dataset.new(query_params: { uid: 33 })
331
+ # users.add_query_params(login: 'jdoe').query_params
247
332
  # # => { uid: 33, :login => 'jdoe' }
248
333
  #
249
334
  # @return [Dataset]
250
335
  #
251
336
  # @api public
252
- def add_params(new_params)
253
- # TODO: Should we merge arrays?
254
- with_options(
255
- params: ::ROM::HTTP::Transformer[:deep_merge][params, new_params]
256
- )
337
+ def add_query_params(new_query_params)
338
+ with_options(query_params: ::ROM::HTTP::Transformer[:deep_merge][query_params,
339
+ new_query_params])
340
+ end
341
+
342
+ # Return a new dataset with replaced request body parameters
343
+ #
344
+ # @param [Hash] body_params the new request body parameters
345
+ #
346
+ # @example
347
+ # users = Dataset.new(body_params: { uid: 33 })
348
+ # users.with_body_params(login: 'jdoe').body_params
349
+ # # => { :login => 'jdoe' }
350
+ #
351
+ # @return [Dataset]
352
+ #
353
+ # @api public
354
+ def with_body_params(body_params)
355
+ with_options(body_params: body_params)
356
+ end
357
+
358
+ # Return a new dataset with merged request body parameters
359
+ #
360
+ # @param [Hash] body_params the new request body parameters to add
361
+ #
362
+ # @example
363
+ # users = Dataset.new(body_params: { uid: 33 })
364
+ # users.add_body_params(login: 'jdoe').body_params
365
+ # # => { uid: 33, :login => 'jdoe' }
366
+ #
367
+ # @return [Dataset]
368
+ #
369
+ # @api public
370
+ def add_body_params(new_body_params)
371
+ with_options(body_params: ::ROM::HTTP::Transformer[:deep_merge][body_params,
372
+ new_body_params])
257
373
  end
258
374
 
259
375
  # Iterate over each response value
@@ -266,34 +382,35 @@ module ROM
266
382
  # @api public
267
383
  def each(&block)
268
384
  return to_enum unless block_given?
385
+
269
386
  response.each(&block)
270
387
  end
271
388
 
272
389
  # Perform an insert over HTTP Post
273
390
  #
274
- # @params [Hash] params The request parameters to send
391
+ # @param [Hash] attributes the attributes to insert
275
392
  #
276
393
  # @return [Array<Hash>]
277
394
  #
278
395
  # @api public
279
- def insert(params)
396
+ def insert(attributes)
280
397
  with_options(
281
398
  request_method: :post,
282
- params: params
399
+ body_params: attributes
283
400
  ).response
284
401
  end
285
402
 
286
403
  # Perform an update over HTTP Put
287
404
  #
288
- # @params [Hash] params The request parameters to send
405
+ # @param [Hash] attributes the attributes to update
289
406
  #
290
407
  # @return [Array<Hash>]
291
408
  #
292
409
  # @api public
293
- def update(params)
410
+ def update(attributes)
294
411
  with_options(
295
412
  request_method: :put,
296
- params: params
413
+ body_params: attributes
297
414
  ).response
298
415
  end
299
416
 
@@ -304,9 +421,7 @@ module ROM
304
421
  #
305
422
  # @api public
306
423
  def delete
307
- with_options(
308
- request_method: :delete
309
- ).response
424
+ with_options(request_method: :delete).response
310
425
  end
311
426
 
312
427
  # Execute the current dataset
@@ -318,37 +433,19 @@ module ROM
318
433
  response_handler.call(request_handler.call(self), self)
319
434
  end
320
435
 
321
- private
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
436
+ memoize :uri, :absolute_path
331
437
 
332
- def request_handler
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
438
+ private
340
439
 
341
- def __new__(*args, &block)
342
- self.class.new(*args, &block)
440
+ # @api private
441
+ def __new__(*args, **kwargs, &block)
442
+ self.class.new(*args, **kwargs, &block)
343
443
  end
344
444
 
445
+ # @api private
345
446
  def join_path(*paths)
346
447
  paths.reject(&:empty?).join(PATH_SEPARATOR)
347
448
  end
348
-
349
- def strip_path(path)
350
- path.sub(%r{\A/}, '')
351
- end
352
449
  end
353
450
  end
354
451
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  module HTTP
3
5
  Error = Class.new(StandardError)
@@ -1,5 +1,10 @@
1
- require 'concurrent'
2
- require 'rom/http/dataset'
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent"
4
+
5
+ require "rom/http/dataset"
6
+ require "rom/http/handlers"
7
+ require "rom/http/mapper_compiler"
3
8
 
4
9
  module ROM
5
10
  module HTTP
@@ -19,7 +24,6 @@ module ROM
19
24
  adapter :http
20
25
 
21
26
  attr_reader :datasets, :config
22
- private :datasets, :config
23
27
 
24
28
  # HTTP gateway interface
25
29
  #
@@ -54,8 +58,7 @@ module ROM
54
58
  #
55
59
  # @api public
56
60
  def dataset(name)
57
- dataset_klass = namespace.const_defined?(:Dataset) ? namespace.const_get(:Dataset) : Dataset
58
- datasets[name] = dataset_klass.new(config.merge(name: name))
61
+ datasets[name] = dataset_class.new(**dataset_options(name))
59
62
  end
60
63
 
61
64
  # Check if dataset exists
@@ -69,8 +72,46 @@ module ROM
69
72
 
70
73
  private
71
74
 
75
+ # Return Dataset class
76
+ #
77
+ # @return [Class]
78
+ #
79
+ # @api private
80
+ def dataset_class
81
+ namespace.const_defined?(:Dataset) ? namespace.const_get(:Dataset) : Dataset
82
+ end
83
+
84
+ # Return Dataset options
85
+ #
86
+ # @return [Class]
87
+ #
88
+ # @api private
89
+ def dataset_options(name)
90
+ config.merge(uri: uri, base_path: name, **default_handlers)
91
+ end
92
+
93
+ # Return default handlers registered in Handlers registry
94
+ #
95
+ # @return [Hash]
96
+ #
97
+ # @api private
98
+ def default_handlers
99
+ if handlers_key = config[:handlers]
100
+ Handlers[handlers_key]
101
+ .map { |key, value| [:"#{key}_handler", value] }.to_h
102
+ else
103
+ EMPTY_HASH
104
+ end
105
+ end
106
+
107
+ # @api private
108
+ def uri
109
+ config.fetch(:uri) { raise Error, "+uri+ configuration missing" }
110
+ end
111
+
112
+ # @api private
72
113
  def namespace
73
- self.class.to_s[/(.*)(?=::)/].split('::').inject(::Object) do |constant, const_name|
114
+ self.class.to_s[/(.*)(?=::)/].split("::").inject(::Object) do |constant, const_name|
74
115
  constant.const_get(const_name)
75
116
  end
76
117
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require "net/http"
5
+ require "json"
6
+
7
+ require "rom/support/inflector"
8
+
9
+ module ROM
10
+ module HTTP
11
+ # Default request/response handlers
12
+ #
13
+ # @api public
14
+ class Handlers
15
+ # Default handler for JSON requests
16
+ #
17
+ # @api public
18
+ class JSONRequest
19
+ # Handle JSON request for the provided dataset
20
+ #
21
+ # @param [Dataset] dataset
22
+ #
23
+ # @return [Array<Hash>]
24
+ #
25
+ # @api public
26
+ def self.call(dataset)
27
+ uri = dataset.uri
28
+
29
+ http = Net::HTTP.new(uri.host, uri.port)
30
+ http.use_ssl = true if uri.scheme.eql?("https")
31
+
32
+ request_class = Net::HTTP.const_get(ROM::Inflector.classify(dataset.request_method))
33
+
34
+ request = request_class.new(uri.request_uri)
35
+
36
+ dataset.headers.each_with_object(request) do |(header, value), request|
37
+ request[header.to_s] = value
38
+ end
39
+
40
+ request.body = JSON.dump(dataset.body_params) if dataset.body_params.any?
41
+
42
+ http.request(request)
43
+ end
44
+ end
45
+
46
+ # Default handler for JSON responses
47
+ #
48
+ # @api public
49
+ class JSONResponse
50
+ # Handle JSON responses
51
+ #
52
+ # @param [Net::HTTP::Response] response
53
+ # @param [Dataset] dataset
54
+ #
55
+ # @return [Array<Hash>]
56
+ #
57
+ # @api public
58
+ def self.call(response, _dataset)
59
+ Array([JSON.parse(response.body)]).flatten(1)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/http/handlers/json"
4
+
5
+ module ROM
6
+ module HTTP
7
+ # Request/response handler registry
8
+ #
9
+ # @api public
10
+ class Handlers
11
+ extend Dry::Container::Mixin
12
+
13
+ register(:json, request: JSONRequest, response: JSONResponse)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/mapper_compiler"
4
+
5
+ module ROM
6
+ module HTTP
7
+ class MapperCompiler < ROM::MapperCompiler
8
+ mapper_options(reject_keys: true)
9
+ end
10
+ end
11
+ end