request_handler 1.1.0 → 2.1.1
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/.circleci/config.yml +75 -0
- data/CHANGELOG.md +35 -0
- data/CODE_OF_CONDUCT.md +69 -0
- data/Gemfile +3 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +241 -45
- data/lib/request_handler.rb +8 -16
- data/lib/request_handler/base.rb +44 -35
- data/lib/request_handler/base_parser.rb +9 -0
- data/lib/request_handler/builder/base.rb +23 -0
- data/lib/request_handler/builder/body_builder.rb +27 -0
- data/lib/request_handler/builder/fieldsets_builder.rb +28 -0
- data/lib/request_handler/builder/fieldsets_resource_builder.rb +17 -0
- data/lib/request_handler/builder/filter_builder.rb +31 -0
- data/lib/request_handler/builder/headers_builder.rb +23 -0
- data/lib/request_handler/builder/include_options_builder.rb +23 -0
- data/lib/request_handler/builder/multipart_builder.rb +22 -0
- data/lib/request_handler/builder/multipart_resource_builder.rb +35 -0
- data/lib/request_handler/builder/options_builder.rb +97 -0
- data/lib/request_handler/builder/page_builder.rb +30 -0
- data/lib/request_handler/builder/page_resource_builder.rb +23 -0
- data/lib/request_handler/builder/query_builder.rb +23 -0
- data/lib/request_handler/builder/sort_options_builder.rb +23 -0
- data/lib/request_handler/concerns/config_helper.rb +25 -0
- data/lib/request_handler/config.rb +33 -0
- data/lib/request_handler/error.rb +14 -3
- data/lib/request_handler/fieldsets_parser.rb +35 -11
- data/lib/request_handler/filter_parser.rb +25 -1
- data/lib/request_handler/header_parser.rb +30 -3
- data/lib/request_handler/include_option_parser.rb +19 -6
- data/lib/request_handler/json_api_document_parser.rb +15 -1
- data/lib/request_handler/multipart_parser.rb +25 -17
- data/lib/request_handler/option_parser.rb +3 -3
- data/lib/request_handler/page_parser.rb +33 -17
- data/lib/request_handler/query_parser.rb +8 -0
- data/lib/request_handler/schema_parser.rb +41 -21
- data/lib/request_handler/sort_option_parser.rb +18 -7
- data/lib/request_handler/validation/definition_engine.rb +35 -0
- data/lib/request_handler/validation/dry_engine.rb +58 -0
- data/lib/request_handler/validation/engine.rb +32 -0
- data/lib/request_handler/validation/errors.rb +5 -0
- data/lib/request_handler/validation/result.rb +17 -0
- data/lib/request_handler/version.rb +1 -1
- data/request_handler.gemspec +9 -8
- metadata +66 -42
- data/.travis.yml +0 -40
data/lib/request_handler.rb
CHANGED
@@ -2,26 +2,18 @@
|
|
2
2
|
|
3
3
|
require 'request_handler/version'
|
4
4
|
require 'request_handler/base'
|
5
|
-
require '
|
6
|
-
require 'dry-validation'
|
5
|
+
require 'request_handler/validation/dry_engine'
|
7
6
|
require 'multi_json'
|
8
7
|
require 'logger'
|
8
|
+
require 'gem_config'
|
9
9
|
|
10
10
|
module RequestHandler
|
11
|
-
|
12
|
-
def configure(&block)
|
13
|
-
configuration.configure(&block)
|
14
|
-
end
|
11
|
+
include GemConfig::Base
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def separator
|
24
|
-
configuration.separator
|
25
|
-
end
|
13
|
+
with_configuration do
|
14
|
+
has :validation_engine
|
15
|
+
has :logger, default: Logger.new(STDOUT)
|
16
|
+
has :separator, classes: [String], default: '__'
|
17
|
+
has :raise_jsonapi_errors, default: false
|
26
18
|
end
|
27
19
|
end
|
data/lib/request_handler/base.rb
CHANGED
@@ -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 '
|
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
|
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
|
|
@@ -51,7 +51,7 @@ module RequestHandler
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def headers
|
54
|
-
@headers ||=
|
54
|
+
@headers ||= parse_headers
|
55
55
|
end
|
56
56
|
|
57
57
|
def body_params
|
@@ -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,43 +100,58 @@ 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
|
107
107
|
|
108
|
+
def parse_headers
|
109
|
+
HeaderParser.new(header_parser_params).run
|
110
|
+
end
|
111
|
+
|
112
|
+
def header_parser_params
|
113
|
+
params = { env: request.env }
|
114
|
+
|
115
|
+
return params if config.nil?
|
116
|
+
|
117
|
+
params.merge(
|
118
|
+
schema: config.lookup('headers.schema'),
|
119
|
+
schema_options: execute_options(config.lookup('headers.options'))
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
108
123
|
def parse_body_params
|
109
124
|
BodyParser.new(
|
110
125
|
request: request,
|
111
|
-
schema: lookup!('body.schema'),
|
112
|
-
schema_options: execute_options(lookup('body.options')),
|
113
|
-
type: lookup('body.type')
|
126
|
+
schema: config.lookup!('body.schema'),
|
127
|
+
schema_options: execute_options(config.lookup('body.options')),
|
128
|
+
type: config.lookup('body.type')
|
114
129
|
).run
|
115
130
|
end
|
116
131
|
|
117
132
|
def parse_multipart_params
|
118
133
|
MultipartsParser.new(
|
119
134
|
request: request,
|
120
|
-
multipart_config: lookup!('multipart')
|
135
|
+
multipart_config: config.lookup!('multipart').to_h
|
121
136
|
).run
|
122
137
|
end
|
123
138
|
|
124
139
|
def parse_fieldsets_params
|
125
140
|
FieldsetsParser.new(params: params,
|
126
|
-
allowed: lookup!('fieldsets.allowed'),
|
127
|
-
required: lookup('fieldsets.required') || []).run
|
141
|
+
allowed: config.lookup!('fieldsets.allowed'),
|
142
|
+
required: config.lookup('fieldsets.required') || []).run
|
128
143
|
end
|
129
144
|
|
130
145
|
def parse_query_params
|
131
146
|
QueryParser.new(
|
132
147
|
params: params,
|
133
|
-
schema: lookup!('query.schema'),
|
134
|
-
schema_options: execute_options(lookup('query.options'))
|
148
|
+
schema: config.lookup!('query.schema'),
|
149
|
+
schema_options: execute_options(config.lookup('query.options'))
|
135
150
|
).run
|
136
151
|
end
|
137
152
|
|
138
153
|
def fetch_defaults(key, default)
|
139
|
-
value = lookup(key)
|
154
|
+
value = config.lookup(key)
|
140
155
|
return default if value.nil?
|
141
156
|
return value unless value.respond_to?(:call)
|
142
157
|
value.call(request)
|
@@ -148,26 +163,20 @@ module RequestHandler
|
|
148
163
|
options.call(self, request)
|
149
164
|
end
|
150
165
|
|
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
166
|
def params
|
162
167
|
raise MissingArgumentError, params: 'is missing' if request.params.nil?
|
163
|
-
raise ExternalArgumentError,
|
168
|
+
raise ExternalArgumentError, [] unless request.params.is_a?(Hash)
|
164
169
|
@params ||= Helper.deep_transform_keys_in_object(request.params) do |k|
|
165
|
-
k.to_s.gsub('.',
|
170
|
+
k.to_s.gsub('.', separator)
|
166
171
|
end
|
167
172
|
end
|
168
173
|
|
169
174
|
def config
|
170
175
|
self.class.instance_variable_get('@config')
|
171
176
|
end
|
177
|
+
|
178
|
+
def separator
|
179
|
+
::RequestHandler.configuration.separator
|
180
|
+
end
|
172
181
|
end
|
173
182
|
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 HeadersBuilder < Base
|
8
|
+
Headers = Struct.new(:schema, :options)
|
9
|
+
|
10
|
+
def create_klass_struct
|
11
|
+
@result = Headers.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def schema(value)
|
15
|
+
@result.schema = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def options(value)
|
19
|
+
@result.options = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
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
|