grape 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -4
- data/Gemfile.lock +13 -13
- data/README.md +290 -12
- data/UPGRADING.md +68 -1
- data/gemfiles/rails_3.gemfile +1 -1
- data/lib/grape.rb +8 -2
- data/lib/grape/api.rb +40 -34
- data/lib/grape/dsl/configuration.rb +2 -115
- data/lib/grape/dsl/desc.rb +101 -0
- data/lib/grape/dsl/headers.rb +16 -0
- data/lib/grape/dsl/helpers.rb +5 -9
- data/lib/grape/dsl/inside_route.rb +3 -11
- data/lib/grape/dsl/logger.rb +20 -0
- data/lib/grape/dsl/parameters.rb +12 -10
- data/lib/grape/dsl/request_response.rb +17 -4
- data/lib/grape/dsl/routing.rb +24 -7
- data/lib/grape/dsl/settings.rb +8 -2
- data/lib/grape/endpoint.rb +30 -26
- data/lib/grape/error_formatter.rb +31 -0
- data/lib/grape/error_formatter/base.rb +0 -28
- data/lib/grape/error_formatter/json.rb +13 -2
- data/lib/grape/error_formatter/txt.rb +3 -1
- data/lib/grape/error_formatter/xml.rb +3 -1
- data/lib/grape/exceptions/base.rb +11 -4
- data/lib/grape/exceptions/incompatible_option_values.rb +1 -1
- data/lib/grape/exceptions/invalid_accept_header.rb +1 -1
- data/lib/grape/exceptions/invalid_formatter.rb +1 -1
- data/lib/grape/exceptions/invalid_message_body.rb +1 -1
- data/lib/grape/exceptions/invalid_version_header.rb +1 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -1
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +1 -1
- data/lib/grape/exceptions/method_not_allowed.rb +10 -0
- data/lib/grape/exceptions/missing_group_type.rb +1 -1
- data/lib/grape/exceptions/missing_mime_type.rb +1 -1
- data/lib/grape/exceptions/missing_option.rb +1 -1
- data/lib/grape/exceptions/missing_vendor_option.rb +1 -1
- data/lib/grape/exceptions/unknown_options.rb +1 -1
- data/lib/grape/exceptions/unknown_parameter.rb +1 -1
- data/lib/grape/exceptions/unknown_validator.rb +1 -1
- data/lib/grape/exceptions/unsupported_group_type.rb +1 -1
- data/lib/grape/exceptions/validation.rb +2 -1
- data/lib/grape/formatter.rb +31 -0
- data/lib/grape/middleware/base.rb +28 -2
- data/lib/grape/middleware/error.rb +24 -1
- data/lib/grape/middleware/formatter.rb +4 -3
- data/lib/grape/middleware/versioner/param.rb +13 -2
- data/lib/grape/parser.rb +29 -0
- data/lib/grape/util/sendfile_response.rb +19 -0
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/params_scope.rb +39 -9
- data/lib/grape/validations/types.rb +16 -0
- data/lib/grape/validations/validators/all_or_none.rb +1 -1
- data/lib/grape/validations/validators/allow_blank.rb +2 -2
- data/lib/grape/validations/validators/at_least_one_of.rb +1 -1
- data/lib/grape/validations/validators/base.rb +26 -0
- data/lib/grape/validations/validators/coerce.rb +16 -14
- data/lib/grape/validations/validators/default.rb +1 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +10 -1
- data/lib/grape/validations/validators/mutual_exclusion.rb +1 -1
- data/lib/grape/validations/validators/presence.rb +1 -1
- data/lib/grape/validations/validators/regexp.rb +2 -2
- data/lib/grape/validations/validators/values.rb +2 -2
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api/custom_validations_spec.rb +156 -21
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +38 -0
- data/spec/grape/api/optional_parameters_in_route_spec.rb +43 -0
- data/spec/grape/api/required_parameters_in_route_spec.rb +37 -0
- data/spec/grape/api_spec.rb +118 -60
- data/spec/grape/dsl/configuration_spec.rb +0 -75
- data/spec/grape/dsl/desc_spec.rb +77 -0
- data/spec/grape/dsl/headers_spec.rb +32 -0
- data/spec/grape/dsl/inside_route_spec.rb +0 -18
- data/spec/grape/dsl/logger_spec.rb +26 -0
- data/spec/grape/dsl/parameters_spec.rb +13 -7
- data/spec/grape/dsl/request_response_spec.rb +17 -3
- data/spec/grape/dsl/routing_spec.rb +8 -1
- data/spec/grape/dsl/settings_spec.rb +42 -0
- data/spec/grape/endpoint_spec.rb +60 -9
- data/spec/grape/exceptions/validation_errors_spec.rb +2 -2
- data/spec/grape/exceptions/validation_spec.rb +7 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +44 -0
- data/spec/grape/middleware/base_spec.rb +100 -0
- data/spec/grape/middleware/exception_spec.rb +1 -2
- data/spec/grape/middleware/formatter_spec.rb +12 -2
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +1 -1
- data/spec/grape/middleware/versioner/header_spec.rb +11 -1
- data/spec/grape/middleware/versioner/param_spec.rb +105 -1
- data/spec/grape/validations/params_scope_spec.rb +77 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +277 -0
- data/spec/grape/validations/validators/coerce_spec.rb +91 -0
- data/spec/grape/validations/validators/default_spec.rb +6 -0
- data/spec/grape/validations/validators/presence_spec.rb +27 -0
- data/spec/grape/validations/validators/regexp_spec.rb +36 -0
- data/spec/grape/validations/validators/values_spec.rb +44 -0
- data/spec/grape/validations_spec.rb +149 -4
- data/spec/spec_helper.rb +1 -0
- metadata +26 -5
- data/lib/grape/formatter/base.rb +0 -31
- data/lib/grape/parser/base.rb +0 -29
- data/pkg/grape-0.13.0.gem +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module Grape
|
2
|
+
module DSL
|
3
|
+
module Headers
|
4
|
+
# Set an individual header or retrieve
|
5
|
+
# all headers that have been set.
|
6
|
+
def header(key = nil, val = nil)
|
7
|
+
if key
|
8
|
+
val ? header[key.to_s] = val : header.delete(key.to_s)
|
9
|
+
else
|
10
|
+
@header ||= {}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
alias_method :headers, :header
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/grape/dsl/helpers.rb
CHANGED
@@ -30,14 +30,10 @@ module Grape
|
|
30
30
|
if block_given? || new_mod
|
31
31
|
mod = new_mod || Module.new
|
32
32
|
define_boolean_in_mod(mod)
|
33
|
-
if new_mod
|
34
|
-
|
35
|
-
|
36
|
-
if block_given?
|
37
|
-
inject_api_helpers_to_mod(mod) do
|
38
|
-
mod.class_eval(&block)
|
39
|
-
end
|
40
|
-
end
|
33
|
+
inject_api_helpers_to_mod(mod) if new_mod
|
34
|
+
inject_api_helpers_to_mod(mod) do
|
35
|
+
mod.class_eval(&block)
|
36
|
+
end if block_given?
|
41
37
|
|
42
38
|
namespace_stackable(:helpers, mod)
|
43
39
|
else
|
@@ -58,7 +54,7 @@ module Grape
|
|
58
54
|
end
|
59
55
|
|
60
56
|
def inject_api_helpers_to_mod(mod, &_block)
|
61
|
-
mod.extend(BaseHelper)
|
57
|
+
mod.extend(BaseHelper) unless mod.is_a?(BaseHelper)
|
62
58
|
yield if block_given?
|
63
59
|
mod.api_changed(self)
|
64
60
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
+
require 'grape/dsl/headers'
|
2
3
|
|
3
4
|
module Grape
|
4
5
|
module DSL
|
5
6
|
module InsideRoute
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
include Grape::DSL::Settings
|
9
|
+
include Grape::DSL::Headers
|
8
10
|
|
9
11
|
# Denotes a situation where a DSL method has been invoked in a
|
10
12
|
# filter which it should not yet be available in
|
@@ -138,16 +140,6 @@ module Grape
|
|
138
140
|
end
|
139
141
|
end
|
140
142
|
|
141
|
-
# Set an individual header or retrieve
|
142
|
-
# all headers that have been set.
|
143
|
-
def header(key = nil, val = nil)
|
144
|
-
if key
|
145
|
-
val ? @header[key.to_s] = val : @header.delete(key.to_s)
|
146
|
-
else
|
147
|
-
@header
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
143
|
# Set response content-type
|
152
144
|
def content_type(val = nil)
|
153
145
|
if val
|
@@ -303,7 +295,7 @@ module Grape
|
|
303
295
|
end
|
304
296
|
|
305
297
|
object_class.ancestors.each do |potential|
|
306
|
-
entity_class ||= (
|
298
|
+
entity_class ||= (namespace_stackable_with_hash(:representations) || {})[potential]
|
307
299
|
end
|
308
300
|
|
309
301
|
entity_class ||= object_class.const_get(:Entity) if object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Grape
|
2
|
+
module DSL
|
3
|
+
module Logger
|
4
|
+
include Grape::DSL::Settings
|
5
|
+
|
6
|
+
attr_writer :logger
|
7
|
+
|
8
|
+
# Set or retrive the configured logger. If none was configured, this
|
9
|
+
# method will create a new one, logging to stdout.
|
10
|
+
# @param logger [Object] the new logger to use
|
11
|
+
def logger(logger = nil)
|
12
|
+
if logger
|
13
|
+
global_setting(:logger, logger)
|
14
|
+
else
|
15
|
+
global_setting(:logger) || global_setting(:logger, ::Logger.new($stdout))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/grape/dsl/parameters.rb
CHANGED
@@ -30,7 +30,7 @@ module Grape
|
|
30
30
|
# end
|
31
31
|
# end
|
32
32
|
def use(*names)
|
33
|
-
named_params =
|
33
|
+
named_params = @api.namespace_stackable_with_hash(:named_params) || {}
|
34
34
|
options = names.extract_options!
|
35
35
|
names.each do |name|
|
36
36
|
params_block = named_params.fetch(name) do
|
@@ -98,7 +98,7 @@ module Grape
|
|
98
98
|
orig_attrs = attrs.clone
|
99
99
|
|
100
100
|
opts = attrs.extract_options!.clone
|
101
|
-
opts[:presence] = true
|
101
|
+
opts[:presence] = { value: true, message: opts[:message] }
|
102
102
|
|
103
103
|
if opts[:using]
|
104
104
|
require_required_and_optional_fields(attrs.first, opts)
|
@@ -122,7 +122,7 @@ module Grape
|
|
122
122
|
# check type for optional parameter group
|
123
123
|
if attrs && block_given?
|
124
124
|
fail Grape::Exceptions::MissingGroupTypeError.new if type.nil?
|
125
|
-
fail Grape::Exceptions::UnsupportedGroupTypeError.new unless
|
125
|
+
fail Grape::Exceptions::UnsupportedGroupTypeError.new unless Grape::Validations::Types.group?(type)
|
126
126
|
end
|
127
127
|
|
128
128
|
if opts[:using]
|
@@ -137,25 +137,25 @@ module Grape
|
|
137
137
|
# Disallow the given parameters to be present in the same request.
|
138
138
|
# @param attrs [*Symbol] parameters to validate
|
139
139
|
def mutually_exclusive(*attrs)
|
140
|
-
validates(attrs, mutual_exclusion: true)
|
140
|
+
validates(attrs, mutual_exclusion: { value: true, message: extract_message_option(attrs) })
|
141
141
|
end
|
142
142
|
|
143
143
|
# Require exactly one of the given parameters to be present.
|
144
144
|
# @param (see #mutually_exclusive)
|
145
145
|
def exactly_one_of(*attrs)
|
146
|
-
validates(attrs, exactly_one_of: true)
|
146
|
+
validates(attrs, exactly_one_of: { value: true, message: extract_message_option(attrs) })
|
147
147
|
end
|
148
148
|
|
149
149
|
# Require at least one of the given parameters to be present.
|
150
150
|
# @param (see #mutually_exclusive)
|
151
151
|
def at_least_one_of(*attrs)
|
152
|
-
validates(attrs, at_least_one_of: true)
|
152
|
+
validates(attrs, at_least_one_of: { value: true, message: extract_message_option(attrs) })
|
153
153
|
end
|
154
154
|
|
155
155
|
# Require that either all given params are present, or none are.
|
156
156
|
# @param (see #mutually_exclusive)
|
157
157
|
def all_or_none_of(*attrs)
|
158
|
-
validates(attrs, all_or_none_of: true)
|
158
|
+
validates(attrs, all_or_none_of: { value: true, message: extract_message_option(attrs) })
|
159
159
|
end
|
160
160
|
|
161
161
|
# Define a block of validations which should be applied if and only if
|
@@ -165,9 +165,11 @@ module Grape
|
|
165
165
|
# @raise Grape::Exceptions::UnknownParameter if `attr` has not been
|
166
166
|
# defined in this scope yet
|
167
167
|
# @yield a parameter definition DSL
|
168
|
-
def given(
|
169
|
-
|
170
|
-
|
168
|
+
def given(*attrs, &block)
|
169
|
+
attrs.each do |attr|
|
170
|
+
fail Grape::Exceptions::UnknownParameter.new(attr) unless declared_param?(attr)
|
171
|
+
end
|
172
|
+
new_lateral_scope(dependent_on: attrs, &block)
|
171
173
|
end
|
172
174
|
|
173
175
|
# Test for whether a certain parameter has been defined in this params
|
@@ -20,7 +20,7 @@ module Grape
|
|
20
20
|
if new_format
|
21
21
|
namespace_inheritable(:format, new_format.to_sym)
|
22
22
|
# define the default error formatters
|
23
|
-
namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter
|
23
|
+
namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter.formatter_for(new_format, {}))
|
24
24
|
# define a single mime type
|
25
25
|
mime_type = content_types[new_format.to_sym]
|
26
26
|
fail Grape::Exceptions::MissingMimeType.new(new_format) unless mime_type
|
@@ -43,7 +43,7 @@ module Grape
|
|
43
43
|
# Specify a default error formatter.
|
44
44
|
def default_error_formatter(new_formatter_name = nil)
|
45
45
|
if new_formatter_name
|
46
|
-
new_formatter = Grape::ErrorFormatter
|
46
|
+
new_formatter = Grape::ErrorFormatter.formatter_for(new_formatter_name, {})
|
47
47
|
namespace_inheritable(:default_error_formatter, new_formatter)
|
48
48
|
else
|
49
49
|
namespace_inheritable(:default_error_formatter)
|
@@ -68,7 +68,7 @@ module Grape
|
|
68
68
|
|
69
69
|
# All available content types.
|
70
70
|
def content_types
|
71
|
-
c_types =
|
71
|
+
c_types = namespace_stackable_with_hash(:content_types)
|
72
72
|
Grape::ContentTypes.content_types_for c_types
|
73
73
|
end
|
74
74
|
|
@@ -105,7 +105,10 @@ module Grape
|
|
105
105
|
end
|
106
106
|
|
107
107
|
options = args.extract_options!
|
108
|
-
|
108
|
+
if block_given? && options.key?(:with)
|
109
|
+
fail ArgumentError, 'both :with option and block cannot be passed'
|
110
|
+
end
|
111
|
+
handler ||= extract_with(options)
|
109
112
|
|
110
113
|
if args.include?(:all)
|
111
114
|
namespace_inheritable(:rescue_all, true)
|
@@ -149,6 +152,16 @@ module Grape
|
|
149
152
|
fail Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with] && options[:with].is_a?(Class)
|
150
153
|
namespace_stackable(:representations, model_class => options[:with])
|
151
154
|
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def extract_with(options)
|
159
|
+
return unless options.key?(:with)
|
160
|
+
with_option = options[:with]
|
161
|
+
return with_option if with_option.instance_of?(Proc)
|
162
|
+
return if with_option.instance_of?(Symbol) || with_option.instance_of?(String)
|
163
|
+
fail ArgumentError, "with: #{with_option.class}, expected Symbol, String or Proc"
|
164
|
+
end
|
152
165
|
end
|
153
166
|
end
|
154
167
|
end
|
data/lib/grape/dsl/routing.rb
CHANGED
@@ -7,7 +7,7 @@ module Grape
|
|
7
7
|
include Grape::DSL::Configuration
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
attr_reader :endpoints, :routes
|
10
|
+
attr_reader :endpoints, :routes
|
11
11
|
|
12
12
|
# Specify an API version.
|
13
13
|
#
|
@@ -46,8 +46,6 @@ module Grape
|
|
46
46
|
namespace_inheritable(:version, args)
|
47
47
|
namespace_inheritable(:version_options, options)
|
48
48
|
end
|
49
|
-
|
50
|
-
# reset_validations!
|
51
49
|
end
|
52
50
|
|
53
51
|
@versions.last unless @versions.nil?
|
@@ -58,6 +56,16 @@ module Grape
|
|
58
56
|
namespace_inheritable(:root_prefix, prefix)
|
59
57
|
end
|
60
58
|
|
59
|
+
# Create a scope without affecting the URL.
|
60
|
+
#
|
61
|
+
# @param _name [Symbol] Purely placebo, just allows to name the scope to
|
62
|
+
# make the code more readable.
|
63
|
+
def scope(_name = nil, &block)
|
64
|
+
within_namespace do
|
65
|
+
nest(block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
61
69
|
# Do not route HEAD requests to GET requests automatically.
|
62
70
|
def do_not_route_head!
|
63
71
|
namespace_inheritable(:do_not_route_head, true)
|
@@ -81,8 +89,6 @@ module Grape
|
|
81
89
|
|
82
90
|
in_setting = app.top_level_setting
|
83
91
|
|
84
|
-
# app.regenerate_endpoints(in_setting)
|
85
|
-
|
86
92
|
app.change!
|
87
93
|
change!
|
88
94
|
end
|
@@ -115,7 +121,7 @@ module Grape
|
|
115
121
|
path: paths,
|
116
122
|
for: self,
|
117
123
|
route_options: ({
|
118
|
-
params:
|
124
|
+
params: namespace_stackable_with_hash(:params) || {}
|
119
125
|
}).deep_merge(route_setting(:description) || {}).deep_merge(route_options || {})
|
120
126
|
}
|
121
127
|
|
@@ -175,9 +181,14 @@ module Grape
|
|
175
181
|
|
176
182
|
# Remove all defined routes.
|
177
183
|
def reset_routes!
|
184
|
+
endpoints.each(&:reset_routes!)
|
178
185
|
@routes = nil
|
179
186
|
end
|
180
187
|
|
188
|
+
def reset_endpoints!
|
189
|
+
@endpoints = []
|
190
|
+
end
|
191
|
+
|
181
192
|
# Thie method allows you to quickly define a parameter route segment
|
182
193
|
# in your API.
|
183
194
|
#
|
@@ -185,7 +196,13 @@ module Grape
|
|
185
196
|
# @option options [Regexp] You may supply a regular expression that the declared parameter must meet.
|
186
197
|
def route_param(param, options = {}, &block)
|
187
198
|
options = options.dup
|
188
|
-
options[:requirements] = {
|
199
|
+
options[:requirements] = {
|
200
|
+
param.to_sym => options[:requirements]
|
201
|
+
} if options[:requirements].is_a?(Regexp)
|
202
|
+
|
203
|
+
Grape::Validations::ParamsScope.new(api: self) do
|
204
|
+
requires param, type: options[:type]
|
205
|
+
end if options.key?(:type)
|
189
206
|
namespace(":#{param}", options, &block)
|
190
207
|
end
|
191
208
|
|
data/lib/grape/dsl/settings.rb
CHANGED
@@ -71,7 +71,7 @@ module Grape
|
|
71
71
|
|
72
72
|
# (see #unset_global_setting)
|
73
73
|
def unset_namespace_setting(key)
|
74
|
-
unset :
|
74
|
+
unset :namespace, key
|
75
75
|
end
|
76
76
|
|
77
77
|
# (see #global_setting)
|
@@ -94,6 +94,12 @@ module Grape
|
|
94
94
|
get_or_set :namespace_stackable, key, value
|
95
95
|
end
|
96
96
|
|
97
|
+
def namespace_stackable_with_hash(key)
|
98
|
+
settings = get_or_set :namespace_stackable, key, nil
|
99
|
+
return if settings.blank?
|
100
|
+
settings.each_with_object({}) { |value, result| result.deep_merge!(value) }
|
101
|
+
end
|
102
|
+
|
97
103
|
# (see #unset_global_setting)
|
98
104
|
def unset_namespace_stackable(key)
|
99
105
|
unset :namespace_stackable, key
|
@@ -106,7 +112,7 @@ module Grape
|
|
106
112
|
|
107
113
|
# (see #unset_global_setting)
|
108
114
|
def unset_api_class_setting(key)
|
109
|
-
unset :
|
115
|
+
unset :api_class, key
|
110
116
|
end
|
111
117
|
|
112
118
|
# Fork our inheritable settings to a new instance, copied from our
|
data/lib/grape/endpoint.rb
CHANGED
@@ -5,12 +5,11 @@ module Grape
|
|
5
5
|
# from inside a `get`, `post`, etc.
|
6
6
|
class Endpoint
|
7
7
|
include Grape::DSL::Settings
|
8
|
+
include Grape::DSL::InsideRoute
|
8
9
|
|
9
10
|
attr_accessor :block, :source, :options
|
10
11
|
attr_reader :env, :request, :headers, :params
|
11
12
|
|
12
|
-
include Grape::DSL::InsideRoute
|
13
|
-
|
14
13
|
class << self
|
15
14
|
def new(*args, &block)
|
16
15
|
if self == Endpoint
|
@@ -115,7 +114,7 @@ module Grape
|
|
115
114
|
end
|
116
115
|
|
117
116
|
def reset_routes!
|
118
|
-
endpoints.
|
117
|
+
endpoints.each(&:reset_routes!) if endpoints
|
119
118
|
@namespace = nil
|
120
119
|
@routes = nil
|
121
120
|
end
|
@@ -126,7 +125,7 @@ module Grape
|
|
126
125
|
e.mount_in(route_set)
|
127
126
|
end
|
128
127
|
else
|
129
|
-
|
128
|
+
reset_routes!
|
130
129
|
|
131
130
|
routes.each do |route|
|
132
131
|
methods = [route.route_method]
|
@@ -243,20 +242,7 @@ module Grape
|
|
243
242
|
|
244
243
|
run_filters before_validations, :before_validation
|
245
244
|
|
246
|
-
|
247
|
-
validation_errors = []
|
248
|
-
|
249
|
-
route_setting(:saved_validations).each do |validator|
|
250
|
-
begin
|
251
|
-
validator.validate!(params)
|
252
|
-
rescue Grape::Exceptions::Validation => e
|
253
|
-
validation_errors << e
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
if validation_errors.any?
|
258
|
-
fail Grape::Exceptions::ValidationErrors, errors: validation_errors, headers: header
|
259
|
-
end
|
245
|
+
run_validators validations, request
|
260
246
|
|
261
247
|
run_filters after_validations, :after_validation
|
262
248
|
|
@@ -276,14 +262,14 @@ module Grape
|
|
276
262
|
b.use Rack::Head
|
277
263
|
b.use Grape::Middleware::Error,
|
278
264
|
format: namespace_inheritable(:format),
|
279
|
-
content_types:
|
265
|
+
content_types: namespace_stackable_with_hash(:content_types),
|
280
266
|
default_status: namespace_inheritable(:default_error_status),
|
281
267
|
rescue_all: namespace_inheritable(:rescue_all),
|
282
268
|
default_error_formatter: namespace_inheritable(:default_error_formatter),
|
283
|
-
error_formatters:
|
284
|
-
rescue_options:
|
285
|
-
rescue_handlers:
|
286
|
-
base_only_rescue_handlers:
|
269
|
+
error_formatters: namespace_stackable_with_hash(:error_formatters),
|
270
|
+
rescue_options: namespace_stackable_with_hash(:rescue_options) || {},
|
271
|
+
rescue_handlers: namespace_stackable_with_hash(:rescue_handlers) || {},
|
272
|
+
base_only_rescue_handlers: namespace_stackable_with_hash(:base_only_rescue_handlers) || {},
|
287
273
|
all_rescue_handler: namespace_inheritable(:all_rescue_handler)
|
288
274
|
|
289
275
|
(namespace_stackable(:middleware) || []).each do |m|
|
@@ -307,9 +293,9 @@ module Grape
|
|
307
293
|
b.use Grape::Middleware::Formatter,
|
308
294
|
format: namespace_inheritable(:format),
|
309
295
|
default_format: namespace_inheritable(:default_format) || :txt,
|
310
|
-
content_types:
|
311
|
-
formatters:
|
312
|
-
parsers:
|
296
|
+
content_types: namespace_stackable_with_hash(:content_types),
|
297
|
+
formatters: namespace_stackable_with_hash(:formatters),
|
298
|
+
parsers: namespace_stackable_with_hash(:parsers)
|
313
299
|
|
314
300
|
b.run ->(env) { env[Grape::Env::API_ENDPOINT].run }
|
315
301
|
|
@@ -346,6 +332,20 @@ module Grape
|
|
346
332
|
end
|
347
333
|
end
|
348
334
|
|
335
|
+
def run_validators(validators, request)
|
336
|
+
validation_errors = []
|
337
|
+
|
338
|
+
validators.each do |validator|
|
339
|
+
begin
|
340
|
+
validator.validate(request)
|
341
|
+
rescue Grape::Exceptions::Validation => e
|
342
|
+
validation_errors << e
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
validation_errors.any? && fail(Grape::Exceptions::ValidationErrors, errors: validation_errors, headers: header)
|
347
|
+
end
|
348
|
+
|
349
349
|
def run_filters(filters, type = :other)
|
350
350
|
ActiveSupport::Notifications.instrument('endpoint_run_filters.grape', endpoint: self, filters: filters, type: type) do
|
351
351
|
(filters || []).each do |filter|
|
@@ -371,5 +371,9 @@ module Grape
|
|
371
371
|
def afters
|
372
372
|
namespace_stackable(:afters) || []
|
373
373
|
end
|
374
|
+
|
375
|
+
def validations
|
376
|
+
route_setting(:saved_validations) || []
|
377
|
+
end
|
374
378
|
end
|
375
379
|
end
|