request_handler 1.3.0 → 2.0.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile +2 -0
  4. data/README.md +167 -29
  5. data/lib/request_handler/base.rb +27 -33
  6. data/lib/request_handler/base_parser.rb +9 -0
  7. data/lib/request_handler/builder/base.rb +23 -0
  8. data/lib/request_handler/builder/body_builder.rb +27 -0
  9. data/lib/request_handler/builder/fieldsets_builder.rb +28 -0
  10. data/lib/request_handler/builder/fieldsets_resource_builder.rb +17 -0
  11. data/lib/request_handler/builder/filter_builder.rb +31 -0
  12. data/lib/request_handler/builder/include_options_builder.rb +23 -0
  13. data/lib/request_handler/builder/multipart_builder.rb +22 -0
  14. data/lib/request_handler/builder/multipart_resource_builder.rb +35 -0
  15. data/lib/request_handler/builder/options_builder.rb +88 -0
  16. data/lib/request_handler/builder/page_builder.rb +30 -0
  17. data/lib/request_handler/builder/page_resource_builder.rb +23 -0
  18. data/lib/request_handler/builder/query_builder.rb +23 -0
  19. data/lib/request_handler/builder/sort_options_builder.rb +23 -0
  20. data/lib/request_handler/concerns/config_helper.rb +25 -0
  21. data/lib/request_handler/config.rb +33 -0
  22. data/lib/request_handler/fieldsets_parser.rb +5 -4
  23. data/lib/request_handler/include_option_parser.rb +2 -2
  24. data/lib/request_handler/multipart_parser.rb +8 -11
  25. data/lib/request_handler/option_parser.rb +1 -1
  26. data/lib/request_handler/page_parser.rb +19 -10
  27. data/lib/request_handler/schema_parser.rb +8 -4
  28. data/lib/request_handler/sort_option_parser.rb +2 -2
  29. data/lib/request_handler/validation/definition_engine.rb +2 -1
  30. data/lib/request_handler/validation/dry_engine.rb +24 -16
  31. data/lib/request_handler/version.rb +1 -1
  32. data/lib/request_handler.rb +7 -22
  33. data/request_handler.gemspec +2 -4
  34. metadata +33 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbf5f683f749e9a5431fe1d07a250c43e72446ddc4fdbb472acd7b06d737fad6
4
- data.tar.gz: e12067caf9c5ec19b306a00d89666fac1a862449f8a68d17cb3ccda42e4a0cde
3
+ metadata.gz: c6f03be51da1bccf44ba08a55724d6cd68c8dd43817e5b1e74f427b9ae1164f7
4
+ data.tar.gz: 942131e22d64ee316f7e7c690c9c1a6af0d5c589459d2bc77786e86a940fe342
5
5
  SHA512:
6
- metadata.gz: df12c3277ca4cb9d73bd8a1661427db90b257bc263e10f40344775a4e3f6f7c8f558a5873cfacab95d888cd7d3ea6e835b72ebc2aa9c176117196530e5a585a2
7
- data.tar.gz: a53b49ccdfde6d9fb929263729972bc5732f01e2997848299ce1dbec187be23a565b5a745ca00dc6cd5765b20bff62ccc2b729abd80bb8ad3965f1ce457e4808
6
+ metadata.gz: f50ec83b0dc218d07d9f9703f929696f761dfd812e2a1dd5230d2e901f20ac1c4141d8674a332d08ecf3297dd7e3a3af4514e7330e37d341db92efc1dc660714
7
+ data.tar.gz: 7e0b0d58b1f0fd697432c9e3f0fb4447b983510bc643acde7713db1c3bc8de23a4209bd45e80ce9f255458ba0c83c5dbd9f22eca672280c98363e85a6cd3c429
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.0.0] - 2019-11-19
8
+ ### Changed
9
+ - BREAKING: Required configuration of validation engine
10
+ - BREAKING: Dynamic resource keys in config DSL are not supported anymore and
11
+ have to be defined via the `resource` key
12
+
13
+ ### Added
14
+ - Support for dry-* 1.x
15
+
16
+ ### Removed
17
+ - BREAKING: Dry dependencies were removed and should manually be added
18
+ - BREAKING: Support for config inheritance
19
+ - BREAKING: Support for dry-* 0.x
20
+
7
21
  ## [1.3.0] - 2019-05-21
8
22
  ### Added
9
23
  - Serializable JSONAPI error objects out of validation failures
data/Gemfile CHANGED
@@ -9,5 +9,7 @@ group :development, :test do
9
9
  gem 'danger'
10
10
  gem 'danger-commit_lint'
11
11
  gem 'danger-rubocop'
12
+ gem 'dry-types', '~> 1.0'
13
+ gem 'dry-validation', '~> 1.0'
12
14
  gem 'rspec_junit_formatter'
13
15
  end
data/README.md CHANGED
@@ -26,34 +26,51 @@ Or install it yourself as:
26
26
 
27
27
  ## Configuration
28
28
 
29
+ You have to chose a validation engine and configure it globally:
30
+ ```ruby
31
+ RequestHandler.configure do |config|
32
+ config.validation_engine = RequestHandler::Validation::DryEngine
33
+ end
34
+ ```
35
+
36
+ If you want to use the included dry engine you also have to add the dry gems to
37
+ your Gemfile:
38
+ ```ruby
39
+ gem 'dry-validation', '~> 1.0'
40
+ gem 'dry-types', '~> 1.0'
41
+ ```
42
+ Note that only dry >= 1.0 is supported.
43
+
29
44
  The default logger and separator can be changed globally:
30
45
 
31
46
  ```ruby
32
- RequestHandler.configure do
33
- logger Logger.new(STDERR)
34
- separator '____'
35
- validation_engine RequestHandler::Validation::DryEngine
47
+ RequestHandler.configure do |config|
48
+ config.logger = Logger.new(STDERR)
49
+ config.separator = '____'
36
50
  end
37
51
  ```
38
52
 
39
53
  JSON:API-style error data can be included in validation errors raised by `RequestHandler`.
40
54
 
41
55
  ```ruby
42
- RequestHandler.configure do
43
- raise_jsonapi_errors = true # default: false
56
+ RequestHandler.configure do |config|
57
+ config.raise_jsonapi_errors = true # default: false
44
58
  end
45
59
  ```
46
60
 
47
61
 
48
62
  ### Validation Engine
49
- Per default this gem uses the `DryEngine` which relies on dry-validation. All
50
- examples in this Readme assume you are using this default engine. However
51
- you can also use the builtin `DefinitionEngine`, which uses [Definition](https://github.com/Goltergaul/definition) as validation library:
63
+ You have to chose a validation engine and configure it globally (see
64
+ configuration section above).
65
+ All examples in this Readme assume you are using the `DryEngine` which relies on
66
+ dry-validation. However you can also use the builtin `DefinitionEngine`, which
67
+ uses [Definition](https://github.com/Goltergaul/definition) as validation
68
+ library:
52
69
 
53
70
  ```ruby
54
- RequestHandler.configure do
71
+ RequestHandler.configure do |config|
55
72
  require 'request_handler/validation/definition_engine'
56
- validation_engine RequestHandler::Validation::DefinitionEngine
73
+ config.validation_engine = RequestHandler::Validation::DefinitionEngine
57
74
  end
58
75
  ```
59
76
 
@@ -85,14 +102,13 @@ defines if the JsonApiDocumentParser or JsonParser is used.
85
102
  If nothing is defined, JsonApiDocumentParser will be used by default.
86
103
 
87
104
  ```ruby
88
- require "dry-validation"
89
105
  require "request_handler"
90
106
  class DemoHandler < RequestHandler::Base
91
107
  options do
92
108
  page do
93
109
  default_size 10
94
110
  max_size 20
95
- comments do
111
+ resource :comments do
96
112
  default_size 20
97
113
  max_size 100
98
114
  end
@@ -108,11 +124,11 @@ class DemoHandler < RequestHandler::Base
108
124
 
109
125
  filter do
110
126
  schema(
111
- Dry::Validation.Params do
112
- configure do
113
- option :foo
127
+ Class.new(Dry::Validation::Contract) do
128
+ option :foo
129
+ params do
130
+ required(:name).filled(:string)
114
131
  end
115
- required(:name).filled(:str?)
116
132
  end
117
133
  )
118
134
  additional_url_filter %i(user_id id)
@@ -122,8 +138,8 @@ class DemoHandler < RequestHandler::Base
122
138
 
123
139
  query do
124
140
  schema(
125
- Dry::Validation.Params do
126
- optional(:name).filled(:str?)
141
+ Dry::Schema.Params do
142
+ optional(:name).filled(:string)
127
143
  end
128
144
  )
129
145
  end
@@ -131,11 +147,11 @@ class DemoHandler < RequestHandler::Base
131
147
  body do
132
148
  type :jsonapi
133
149
  schema(
134
- Dry::Validation.JSON do
135
- configure do
136
- option :foo
150
+ Class.new(Dry::Validation::Contract) do
151
+ option :foo
152
+ json do
153
+ required(:id).filled(:string)
137
154
  end
138
- required(:id).filled(:str?)
139
155
  end
140
156
  )
141
157
  options(->(_handler, _request) { { foo: "bar" } })
@@ -208,19 +224,19 @@ file related to the question
208
224
  class CreateQuestionHandler < RequestHandler::Base
209
225
  options do
210
226
  multipart do
211
- question do
227
+ resource :question do
212
228
  required true
213
229
  type "json"
214
230
  schema(
215
- Dry::Validation.JSON do
216
- required(:id).filled(:str?)
217
- required(:type).filled(:str?)
218
- required(:content).filled(:str?)
231
+ Dry::Schema.JSON do
232
+ required(:id).filled(:string)
233
+ required(:type).filled(:string)
234
+ required(:content).filled(:string)
219
235
  end
220
236
  )
221
237
  end
222
238
 
223
- file do
239
+ resource :file do
224
240
  # no validation necessary
225
241
  end
226
242
  end
@@ -317,6 +333,128 @@ get "/users/:user_id/posts" do
317
333
  end
318
334
  ```
319
335
 
336
+ ## v1 to v2 migration guide
337
+ Multiple breaking changes were introduced with request_handler 2.0. This section
338
+ describes which steps have to be taken in order to migrate from 1.x to 2.0.
339
+
340
+ ### Configure validation engine
341
+ By default the DryEngine was used in 1.0. You now have to explicitly configure
342
+ a validation engine:
343
+
344
+ ```ruby
345
+ RequestHandler.configure do |config|
346
+ config.validation_engine = RequestHandler::Validation::DryEngine
347
+ end
348
+ ```
349
+
350
+ ### Add dry dependency if you use the DryEngine
351
+ Since the DryEngine is not configured by default anymore, the dependency to the
352
+ dry gems could be removed from request_handler. If you use the DryEngine
353
+ simply add the dry-gems to your Gemfile:
354
+
355
+ ```ruby
356
+ gem 'dry-validation', '~> 1.0'
357
+ gem 'dry-types', '~> 1.0'
358
+ ```
359
+ Note that only dry >= 1.0 is supported.
360
+
361
+ ### Define custom resources via the `resource` key
362
+ In request_handler 1.x it was possible to define custom resource names like this:
363
+
364
+ ```ruby
365
+ options do
366
+ fieldsets do
367
+ allowed do
368
+ posts schema
369
+ end
370
+ end
371
+ end
372
+ ```
373
+
374
+ This was possible in multiple places (`page`, `multipart`, `fieldsets.allowed`).
375
+ Starting with version 2.0 you will have to define those custom resources via the
376
+ `resource` key:
377
+
378
+ ```ruby
379
+ options do
380
+ fieldsets do
381
+ allowed do
382
+ resource :posts, schema
383
+ end
384
+ end
385
+ end
386
+ ```
387
+
388
+ ### Use dry-* 1.x instead of dry-* 0.x if you use the DryEngine
389
+ Some of the most common required changes are listed here:
390
+
391
+ * Use `Dry::Schema.Params` instead of `Dry::Validation.Schema`
392
+ * Use `Dry::Schema.JSON` instead of `Dry::Validation.JSON`
393
+ * If you use some more complex validation rules with options like this:
394
+
395
+ ```
396
+ Dry::Validation.Params do
397
+ configure do
398
+ option :query_id
399
+ end
400
+ required(:id).value(eql?: query_id)
401
+ end
402
+
403
+ options(->(_parser, request) { { query_id: request.params['id'] } })
404
+ ```
405
+
406
+ please rewrite it using `Dry::Validation::Contract` like this:
407
+
408
+ ```
409
+ Class.new(Dry::Validation::Contract) do
410
+ option :query_id
411
+ params do
412
+ required(:id).value(:string)
413
+ end
414
+ rule(:id) do
415
+ key.failure('invalid id') unless values[:id] == query_id
416
+ end
417
+ end)
418
+ options(->(_parser, request) { { query_id: request.params['id'] } })
419
+ ```
420
+
421
+ A useful guide for upgrading to dry 1 types, validations and schemas can be
422
+ found [here](https://www.morozov.is/2019/05/31/upgrading-dry-gems.html).
423
+
424
+ Also please refer to the official docs of
425
+ [dry-schema](https://dry-rb.org/gems/dry-schema) and
426
+ [dry-validation](https://dry-rb.org/gems/dry-validation).
427
+
428
+ ### Remove config inheritance
429
+ It was possible to (partially) overwrite configs defined in a request-handler
430
+ super-class:
431
+ ```
432
+ class Parent < RequestHandler::Base
433
+ options do
434
+ page do
435
+ comments do
436
+ default_size 20
437
+ end
438
+ end
439
+ end
440
+ end
441
+ ```
442
+
443
+ ```ruby
444
+ class Child < Parent
445
+ options do
446
+ page do
447
+ comments do
448
+ default_size 10
449
+ end
450
+ end
451
+ end
452
+ end
453
+ ```
454
+
455
+ Support for this has been fully removed. If you overwrite configs in subclasses
456
+ please remove the inheritance and define the two request-handlers separately.
457
+
320
458
  ## Development
321
459
 
322
460
  After checking out the repo, run `bin/setup` to install dependencies. You can
@@ -10,22 +10,22 @@ require 'request_handler/multipart_parser'
10
10
  require 'request_handler/fieldsets_parser'
11
11
  require 'request_handler/query_parser'
12
12
  require 'request_handler/helper'
13
- require 'confstruct'
13
+ require 'request_handler/builder/options_builder'
14
+ require 'request_handler/concerns/config_helper'
15
+ require 'request_handler/config'
16
+
14
17
  module RequestHandler
15
18
  class Base
19
+ include RequestHandler::Concerns::ConfigHelper
20
+
16
21
  class << self
17
22
  def options(&block)
18
- @config ||= ::Confstruct::Configuration.new
19
- @config.configure(&block)
20
- end
21
-
22
- def inherited(subclass)
23
- return if @config.nil?
24
- subclass.config = @config.deep_copy
23
+ @config = Config.new(&block)
25
24
  end
26
25
 
27
26
  attr_accessor :config
28
27
  end
28
+
29
29
  def initialize(request:)
30
30
  raise MissingArgumentError, request: 'is missing' if request.nil?
31
31
  @request = request
@@ -38,7 +38,7 @@ module RequestHandler
38
38
  def page_params
39
39
  @page_params ||= PageParser.new(
40
40
  params: params,
41
- page_config: lookup!('page')
41
+ page_config: config.lookup!('page')
42
42
  ).run
43
43
  end
44
44
 
@@ -82,9 +82,9 @@ module RequestHandler
82
82
  defaults = fetch_defaults('filter.defaults', {})
83
83
  defaults.merge(FilterParser.new(
84
84
  params: params,
85
- schema: lookup!('filter.schema'),
86
- additional_url_filter: lookup('filter.additional_url_filter'),
87
- schema_options: execute_options(lookup('filter.options'))
85
+ schema: config.lookup!('filter.schema'),
86
+ additional_url_filter: config.lookup('filter.additional_url_filter'),
87
+ schema_options: execute_options(config.lookup('filter.options'))
88
88
  ).run)
89
89
  end
90
90
 
@@ -100,7 +100,7 @@ module RequestHandler
100
100
  defaults = fetch_defaults("#{type}.defaults", [])
101
101
  result = parser.new(
102
102
  params: params,
103
- allowed_options_type: lookup!("#{type}.allowed")
103
+ allowed_options_type: config.lookup!("#{type}.allowed")
104
104
  ).run
105
105
  result.empty? ? defaults : result
106
106
  end
@@ -108,35 +108,35 @@ module RequestHandler
108
108
  def parse_body_params
109
109
  BodyParser.new(
110
110
  request: request,
111
- schema: lookup!('body.schema'),
112
- schema_options: execute_options(lookup('body.options')),
113
- type: lookup('body.type')
111
+ schema: config.lookup!('body.schema'),
112
+ schema_options: execute_options(config.lookup('body.options')),
113
+ type: config.lookup('body.type')
114
114
  ).run
115
115
  end
116
116
 
117
117
  def parse_multipart_params
118
118
  MultipartsParser.new(
119
119
  request: request,
120
- multipart_config: lookup!('multipart')
120
+ multipart_config: config.lookup!('multipart').to_h
121
121
  ).run
122
122
  end
123
123
 
124
124
  def parse_fieldsets_params
125
125
  FieldsetsParser.new(params: params,
126
- allowed: lookup!('fieldsets.allowed'),
127
- required: lookup('fieldsets.required') || []).run
126
+ allowed: config.lookup!('fieldsets.allowed'),
127
+ required: config.lookup('fieldsets.required') || []).run
128
128
  end
129
129
 
130
130
  def parse_query_params
131
131
  QueryParser.new(
132
132
  params: params,
133
- schema: lookup!('query.schema'),
134
- schema_options: execute_options(lookup('query.options'))
133
+ schema: config.lookup!('query.schema'),
134
+ schema_options: execute_options(config.lookup('query.options'))
135
135
  ).run
136
136
  end
137
137
 
138
138
  def fetch_defaults(key, default)
139
- value = lookup(key)
139
+ value = config.lookup(key)
140
140
  return default if value.nil?
141
141
  return value unless value.respond_to?(:call)
142
142
  value.call(request)
@@ -148,26 +148,20 @@ module RequestHandler
148
148
  options.call(self, request)
149
149
  end
150
150
 
151
- def lookup!(key)
152
- config.lookup!(key).tap do |data|
153
- raise NoConfigAvailableError, key.to_sym => 'is not configured' if data.nil?
154
- end
155
- end
156
-
157
- def lookup(key)
158
- config.lookup!(key)
159
- end
160
-
161
151
  def params
162
152
  raise MissingArgumentError, params: 'is missing' if request.params.nil?
163
153
  raise ExternalArgumentError, [] unless request.params.is_a?(Hash)
164
154
  @params ||= Helper.deep_transform_keys_in_object(request.params) do |k|
165
- k.to_s.gsub('.', ::RequestHandler.separator)
155
+ k.to_s.gsub('.', separator)
166
156
  end
167
157
  end
168
158
 
169
159
  def config
170
160
  self.class.instance_variable_get('@config')
171
161
  end
162
+
163
+ def separator
164
+ ::RequestHandler.configuration.separator
165
+ end
172
166
  end
173
167
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/concerns/config_helper'
4
+
5
+ module RequestHandler
6
+ class BaseParser
7
+ include RequestHandler::Concerns::ConfigHelper
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class Base
8
+ attr_accessor :result
9
+
10
+ def initialize
11
+ create_klass_struct
12
+ end
13
+
14
+ def create_klass_struct
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def build
19
+ result
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class BodyBuilder < Base
8
+ Body = Struct.new(:type, :schema, :options)
9
+
10
+ def create_klass_struct
11
+ @result = Body.new
12
+ end
13
+
14
+ def type(value)
15
+ @result.type = value
16
+ end
17
+
18
+ def schema(value)
19
+ @result.schema = value
20
+ end
21
+
22
+ def options(value)
23
+ @result.options = value
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+ require 'request_handler/builder/fieldsets_resource_builder'
5
+
6
+ module RequestHandler
7
+ module Builder
8
+ class FieldsetsBuilder < Base
9
+ Fieldsets = Struct.new(:allowed, :required)
10
+
11
+ def create_klass_struct
12
+ @result = Fieldsets.new
13
+ end
14
+
15
+ def allowed(&block)
16
+ @result.allowed = build_fieldsets_resource(&block)
17
+ end
18
+
19
+ def required(value)
20
+ @result.required = value
21
+ end
22
+
23
+ def build_fieldsets_resource(&block)
24
+ Docile.dsl_eval(FieldsetsResourceBuilder.new, &block).build
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "request_handler/builder/base"
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class FieldsetsResourceBuilder < Base
8
+ def create_klass_struct
9
+ @result = OpenStruct.new
10
+ end
11
+
12
+ def resource(name, value)
13
+ @result[name.to_sym] = value
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class FilterBuilder < Base
8
+ Filter = Struct.new(:schema, :additional_url_filter, :options, :defaults)
9
+
10
+ def create_klass_struct
11
+ @result = Filter.new
12
+ end
13
+
14
+ def schema(value)
15
+ @result.schema = value
16
+ end
17
+
18
+ def additional_url_filter(value)
19
+ @result.additional_url_filter = value
20
+ end
21
+
22
+ def options(value)
23
+ @result.options = value
24
+ end
25
+
26
+ def defaults(value)
27
+ @result.defaults = value
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class IncludeOptionsBuilder < Base
8
+ IncludeOptions = Struct.new(:allowed, :defaults)
9
+
10
+ def create_klass_struct
11
+ @result = IncludeOptions.new
12
+ end
13
+
14
+ def allowed(value)
15
+ @result.allowed = value
16
+ end
17
+
18
+ def defaults(value)
19
+ @result.defaults = value
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+ require 'request_handler/builder/multipart_resource_builder'
5
+
6
+ module RequestHandler
7
+ module Builder
8
+ class MultipartBuilder < Base
9
+ def create_klass_struct
10
+ @result = OpenStruct.new
11
+ end
12
+
13
+ def resource(name, &block)
14
+ @result[name.to_sym] = build_multipart_resource(&block)
15
+ end
16
+
17
+ def build_multipart_resource(&block)
18
+ Docile.dsl_eval(MultipartResourceBuilder.new, &block).build
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/builder/base'
4
+
5
+ module RequestHandler
6
+ module Builder
7
+ class MultipartResourceBuilder < Base
8
+ MultipartResource = Struct.new(:required, :schema, :type, :options)
9
+
10
+ def create_klass_struct
11
+ @result = MultipartResource.new
12
+ end
13
+
14
+ def type(value)
15
+ @result.type = value
16
+ end
17
+
18
+ def required(value)
19
+ @result.required = value
20
+ end
21
+
22
+ def resource(name, &block)
23
+ @result[name.to_sym] = build_multipart_resource(&block)
24
+ end
25
+
26
+ def schema(value)
27
+ @result.schema = value
28
+ end
29
+
30
+ def options(value)
31
+ @result.options = value
32
+ end
33
+ end
34
+ end
35
+ end