grape 0.13.0 → 0.14.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/Appraisals +9 -4
- data/CHANGELOG.md +28 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +166 -0
- data/README.md +305 -163
- data/Rakefile +30 -33
- data/UPGRADING.md +31 -0
- data/benchmark/simple.rb +27 -0
- data/gemfiles/rack_1.5.2.gemfile +13 -0
- data/gemfiles/rails_3.gemfile +2 -2
- data/gemfiles/rails_4.gemfile +1 -2
- data/grape.gemspec +5 -4
- data/lib/grape.rb +9 -5
- data/lib/grape/dsl/configuration.rb +5 -2
- data/lib/grape/dsl/helpers.rb +8 -3
- data/lib/grape/dsl/inside_route.rb +67 -44
- data/lib/grape/dsl/parameters.rb +21 -12
- data/lib/grape/dsl/request_response.rb +1 -1
- data/lib/grape/dsl/routing.rb +3 -4
- data/lib/grape/endpoint.rb +63 -28
- data/lib/grape/error_formatter/base.rb +6 -6
- data/lib/grape/exceptions/base.rb +5 -5
- data/lib/grape/exceptions/invalid_version_header.rb +10 -0
- data/lib/grape/formatter/serializable_hash.rb +3 -2
- data/lib/grape/locale/en.yml +4 -1
- data/lib/grape/middleware/auth/base.rb +2 -2
- data/lib/grape/middleware/auth/dsl.rb +1 -1
- data/lib/grape/middleware/auth/strategies.rb +1 -1
- data/lib/grape/middleware/base.rb +7 -4
- data/lib/grape/middleware/error.rb +3 -2
- data/lib/grape/middleware/filter.rb +1 -1
- data/lib/grape/middleware/formatter.rb +47 -44
- data/lib/grape/middleware/globals.rb +3 -3
- data/lib/grape/middleware/versioner/accept_version_header.rb +5 -7
- data/lib/grape/middleware/versioner/header.rb +113 -50
- data/lib/grape/middleware/versioner/param.rb +5 -8
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +20 -0
- data/lib/grape/middleware/versioner/path.rb +3 -6
- data/lib/grape/path.rb +3 -3
- data/lib/grape/request.rb +40 -0
- data/lib/grape/util/content_types.rb +9 -9
- data/lib/grape/util/env.rb +22 -0
- data/lib/grape/util/strict_hash_configuration.rb +2 -1
- data/lib/grape/validations/attributes_iterator.rb +8 -3
- data/lib/grape/validations/params_scope.rb +83 -15
- data/lib/grape/validations/types.rb +144 -0
- data/lib/grape/validations/types/build_coercer.rb +53 -0
- data/lib/grape/validations/types/custom_type_coercer.rb +183 -0
- data/lib/grape/validations/types/file.rb +28 -0
- data/lib/grape/validations/types/json.rb +65 -0
- data/lib/grape/validations/types/multiple_type_coercer.rb +76 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +59 -0
- data/lib/grape/validations/types/virtus_collection_patch.rb +16 -0
- data/lib/grape/validations/validators/all_or_none.rb +1 -1
- data/lib/grape/validations/validators/allow_blank.rb +3 -3
- data/lib/grape/validations/validators/base.rb +7 -0
- data/lib/grape/validations/validators/coerce.rb +31 -42
- data/lib/grape/validations/validators/presence.rb +2 -3
- data/lib/grape/validations/validators/regexp.rb +2 -4
- data/lib/grape/validations/validators/values.rb +3 -3
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-0.13.0.gem +0 -0
- data/spec/grape/api/custom_validations_spec.rb +5 -4
- data/spec/grape/api/deeply_included_options_spec.rb +7 -7
- data/spec/grape/api/nested_helpers_spec.rb +4 -2
- data/spec/grape/api/shared_helpers_spec.rb +8 -8
- data/spec/grape/api_spec.rb +88 -54
- data/spec/grape/dsl/configuration_spec.rb +13 -0
- data/spec/grape/dsl/helpers_spec.rb +16 -2
- data/spec/grape/dsl/inside_route_spec.rb +3 -2
- data/spec/grape/dsl/parameters_spec.rb +0 -6
- data/spec/grape/dsl/routing_spec.rb +1 -1
- data/spec/grape/endpoint_spec.rb +61 -20
- data/spec/grape/entity_spec.rb +10 -8
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +1 -15
- data/spec/grape/integration/rack_spec.rb +3 -2
- data/spec/grape/middleware/base_spec.rb +7 -5
- data/spec/grape/middleware/error_spec.rb +16 -15
- data/spec/grape/middleware/exception_spec.rb +45 -43
- data/spec/grape/middleware/formatter_spec.rb +34 -0
- data/spec/grape/middleware/versioner/header_spec.rb +79 -47
- data/spec/grape/path_spec.rb +10 -10
- data/spec/grape/presenters/presenter_spec.rb +2 -2
- data/spec/grape/request_spec.rb +100 -0
- data/spec/grape/validations/params_scope_spec.rb +11 -9
- data/spec/grape/validations/types_spec.rb +95 -0
- data/spec/grape/validations/validators/coerce_spec.rb +335 -2
- data/spec/grape/validations/validators/values_spec.rb +15 -15
- data/spec/grape/validations_spec.rb +53 -24
- data/spec/shared/versioning_examples.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/versioned_helpers.rb +2 -2
- metadata +51 -13
- data/.gitignore +0 -46
- data/.rspec +0 -2
- data/.rubocop.yml +0 -7
- data/.rubocop_todo.yml +0 -84
- data/.travis.yml +0 -20
- data/.yardopts +0 -2
- data/lib/grape/http/request.rb +0 -35
- data/lib/grape/util/parameter_types.rb +0 -58
- data/spec/grape/util/parameter_types_spec.rb +0 -54
data/Rakefile
CHANGED
@@ -17,52 +17,49 @@ end
|
|
17
17
|
task :spec
|
18
18
|
|
19
19
|
require 'rainbow/ext/string' unless String.respond_to?(:color)
|
20
|
+
|
20
21
|
require 'rubocop/rake_task'
|
21
22
|
RuboCop::RakeTask.new
|
22
23
|
|
23
24
|
task default: [:rubocop, :spec]
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
require 'yard'
|
27
|
+
DOC_FILES = ['lib/**/*.rb', 'README.md']
|
28
|
+
|
29
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
30
|
+
t.files = DOC_FILES
|
31
|
+
end
|
28
32
|
|
29
|
-
|
33
|
+
namespace :doc do
|
34
|
+
YARD::Rake::YardocTask.new(:pages) do |t|
|
30
35
|
t.files = DOC_FILES
|
36
|
+
t.options = ['-o', '../grape.doc/docs']
|
31
37
|
end
|
32
38
|
|
33
|
-
namespace :
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
Dir.mkdir(dir)
|
45
|
-
Dir.chdir(dir) do
|
46
|
-
system('git init')
|
47
|
-
system('git remote add origin git@github.com:ruby-grape/grape.git')
|
48
|
-
system('git pull')
|
49
|
-
system('git checkout gh-pages')
|
50
|
-
end
|
39
|
+
namespace :pages do
|
40
|
+
desc 'Check out gh-pages.'
|
41
|
+
task :checkout do
|
42
|
+
dir = File.dirname(__FILE__) + '/../grape.doc'
|
43
|
+
unless Dir.exist?(dir)
|
44
|
+
Dir.mkdir(dir)
|
45
|
+
Dir.chdir(dir) do
|
46
|
+
system('git init')
|
47
|
+
system('git remote add origin git@github.com:ruby-grape/grape.git')
|
48
|
+
system('git pull')
|
49
|
+
system('git checkout gh-pages')
|
51
50
|
end
|
52
51
|
end
|
52
|
+
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
54
|
+
desc 'Generate and publish YARD docs to GitHub pages.'
|
55
|
+
task publish: ['doc:pages:checkout', 'doc:pages'] do
|
56
|
+
Dir.chdir(File.dirname(__FILE__) + '/../grape.doc') do
|
57
|
+
system('git checkout gh-pages')
|
58
|
+
system('git add .')
|
59
|
+
system('git add -u')
|
60
|
+
system("git commit -m 'Generating docs for version #{Grape::VERSION}.'")
|
61
|
+
system('git push origin gh-pages')
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
66
|
-
rescue LoadError
|
67
|
-
puts 'You need to install YARD.'
|
68
65
|
end
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
Upgrading Grape
|
2
2
|
===============
|
3
3
|
|
4
|
+
### Upgrading to >= 0.14.0
|
5
|
+
|
6
|
+
#### Changes to availability of DSL methods in filters
|
7
|
+
|
8
|
+
The `#declared` method of the route DSL is no longer available in the `before` filter. Using `declared` in a `before` filter will now raise `Grape::DSL::InsideRoute::MethodNotYetAvailable`.
|
9
|
+
|
10
|
+
See [#1074](https://github.com/ruby-grape/grape/issues/1074) for discussion of the issue.
|
11
|
+
|
12
|
+
#### Changes to header versioning and invalid header version handling
|
13
|
+
|
14
|
+
Identical endpoints with different versions now work correctly. A regression introduced in Grape 0.11.0 caused all but the first-mounted version for such an endpoint to wrongly throw an `InvalidAcceptHeader`. As a side effect, requests with a correct vendor but invalid version can no longer be rescued from a `rescue_from` block.
|
15
|
+
|
16
|
+
See [#1114](https://github.com/ruby-grape/grape/pull/1114) for more information.
|
17
|
+
|
18
|
+
#### Bypasses formatters when status code indicates no content
|
19
|
+
|
20
|
+
To be consistent with rack and it's handling of standard responses
|
21
|
+
associated with no content, both default and custom formatters will now
|
22
|
+
be bypassed when processing responses for status codes defined [by rack](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567)
|
23
|
+
|
24
|
+
See [#1190](https://github.com/ruby-grape/grape/pull/1190) for more information.
|
25
|
+
|
26
|
+
#### Redirects respond as plain text with message
|
27
|
+
|
28
|
+
`#redirect` now uses `text/plain` regardless of whether that format has
|
29
|
+
been enabled. This prevents formatters from attempting to serialize the
|
30
|
+
message body and allows for a descriptive message body to be provided - and
|
31
|
+
optionally overridden - that better fulfills the theme of the HTTP spec.
|
32
|
+
|
33
|
+
See [#1194](https://github.com/ruby-grape/grape/pull/1194) for more information.
|
34
|
+
|
4
35
|
### Upgrading to >= 0.12.0
|
5
36
|
|
6
37
|
#### Changes in middleware
|
data/benchmark/simple.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'grape'
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
class API < Grape::API
|
6
|
+
prefix :api
|
7
|
+
version 'v1', using: :path
|
8
|
+
get '/' do
|
9
|
+
'hello'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
options = {
|
14
|
+
method: 'GET'
|
15
|
+
}
|
16
|
+
|
17
|
+
env = Rack::MockRequest.env_for('/api/v1', options)
|
18
|
+
|
19
|
+
10.times do |i|
|
20
|
+
env["HTTP_HEADER#{i}"] = '123'
|
21
|
+
end
|
22
|
+
|
23
|
+
Benchmark.ips do |ips|
|
24
|
+
ips.report('simple') do
|
25
|
+
API.call env
|
26
|
+
end
|
27
|
+
end
|
data/gemfiles/rails_3.gemfile
CHANGED
@@ -3,12 +3,12 @@
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
5
|
gem 'rails', '3.2.19'
|
6
|
+
gem 'rack-cache', '<= 1.2'
|
6
7
|
|
7
8
|
group :development, :test do
|
8
|
-
gem 'rubocop', '~> 0.31.0'
|
9
9
|
gem 'guard'
|
10
10
|
gem 'guard-rspec'
|
11
11
|
gem 'guard-rubocop'
|
12
12
|
end
|
13
13
|
|
14
|
-
gemspec :
|
14
|
+
gemspec path: '../'
|
data/gemfiles/rails_4.gemfile
CHANGED
data/grape.gemspec
CHANGED
@@ -31,11 +31,12 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_development_dependency 'bundler'
|
32
32
|
s.add_development_dependency 'cookiejar'
|
33
33
|
s.add_development_dependency 'rack-contrib'
|
34
|
-
s.add_development_dependency 'mime-types'
|
34
|
+
s.add_development_dependency 'mime-types', '< 3.0'
|
35
35
|
s.add_development_dependency 'appraisal'
|
36
|
+
s.add_development_dependency 'benchmark-ips'
|
37
|
+
s.add_development_dependency 'rubocop', '0.35.1'
|
36
38
|
|
37
|
-
s.files =
|
38
|
-
s.test_files =
|
39
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
39
|
+
s.files = Dir['**/*'].keep_if { |file| File.file?(file) }
|
40
|
+
s.test_files = Dir['spec/**/*']
|
40
41
|
s.require_paths = ['lib']
|
41
42
|
end
|
data/lib/grape.rb
CHANGED
@@ -9,19 +9,21 @@ require 'hashie'
|
|
9
9
|
require 'set'
|
10
10
|
require 'active_support/version'
|
11
11
|
require 'active_support/core_ext/hash/indifferent_access'
|
12
|
-
require 'active_support/
|
13
|
-
require 'active_support/core_ext/object/conversions'
|
12
|
+
require 'active_support/core_ext/object/blank'
|
14
13
|
require 'active_support/core_ext/array/extract_options'
|
14
|
+
require 'active_support/core_ext/array/wrap'
|
15
15
|
require 'active_support/core_ext/hash/deep_merge'
|
16
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
16
17
|
require 'active_support/core_ext/hash/except'
|
17
18
|
require 'active_support/dependencies/autoload'
|
18
19
|
require 'active_support/notifications'
|
19
20
|
require 'multi_json'
|
20
21
|
require 'multi_xml'
|
21
|
-
require 'virtus'
|
22
22
|
require 'i18n'
|
23
23
|
require 'thread'
|
24
24
|
|
25
|
+
require 'virtus'
|
26
|
+
|
25
27
|
I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)
|
26
28
|
|
27
29
|
module Grape
|
@@ -38,7 +40,8 @@ module Grape
|
|
38
40
|
|
39
41
|
autoload :Cookies
|
40
42
|
autoload :Validations
|
41
|
-
autoload :Request
|
43
|
+
autoload :Request
|
44
|
+
autoload :Env, 'grape/util/env'
|
42
45
|
end
|
43
46
|
|
44
47
|
module Http
|
@@ -67,6 +70,7 @@ module Grape
|
|
67
70
|
autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
|
68
71
|
autoload :InvalidMessageBody
|
69
72
|
autoload :InvalidAcceptHeader
|
73
|
+
autoload :InvalidVersionHeader
|
70
74
|
end
|
71
75
|
|
72
76
|
module ErrorFormatter
|
@@ -156,7 +160,6 @@ module Grape
|
|
156
160
|
end
|
157
161
|
|
158
162
|
require 'grape/util/content_types'
|
159
|
-
require 'grape/util/parameter_types'
|
160
163
|
|
161
164
|
require 'grape/validations/validators/base'
|
162
165
|
require 'grape/validations/attributes_iterator'
|
@@ -171,5 +174,6 @@ require 'grape/validations/validators/regexp'
|
|
171
174
|
require 'grape/validations/validators/values'
|
172
175
|
require 'grape/validations/params_scope'
|
173
176
|
require 'grape/validations/validators/all_or_none'
|
177
|
+
require 'grape/validations/types'
|
174
178
|
|
175
179
|
require 'grape/version'
|
@@ -64,6 +64,9 @@ module Grape
|
|
64
64
|
end
|
65
65
|
|
66
66
|
config_class.configure(&config_block)
|
67
|
+
unless options.empty?
|
68
|
+
warn '[DEPRECATION] Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.'
|
69
|
+
end
|
67
70
|
options = config_class.settings
|
68
71
|
else
|
69
72
|
options = options.merge(description: description)
|
@@ -94,8 +97,8 @@ module Grape
|
|
94
97
|
|
95
98
|
# Merge multiple layers of settings into one hash.
|
96
99
|
def stacked_hash_to_hash(settings)
|
97
|
-
return
|
98
|
-
settings.each_with_object(
|
100
|
+
return if settings.blank?
|
101
|
+
settings.each_with_object({}) { |value, result| result.deep_merge!(value) }
|
99
102
|
end
|
100
103
|
|
101
104
|
# Returns an object which configures itself via an instance-context DSL.
|
data/lib/grape/dsl/helpers.rb
CHANGED
@@ -29,6 +29,7 @@ module Grape
|
|
29
29
|
def helpers(new_mod = nil, &block)
|
30
30
|
if block_given? || new_mod
|
31
31
|
mod = new_mod || Module.new
|
32
|
+
define_boolean_in_mod(mod)
|
32
33
|
if new_mod
|
33
34
|
inject_api_helpers_to_mod(new_mod) if new_mod.is_a?(BaseHelper)
|
34
35
|
end
|
@@ -51,6 +52,11 @@ module Grape
|
|
51
52
|
|
52
53
|
protected
|
53
54
|
|
55
|
+
def define_boolean_in_mod(mod)
|
56
|
+
return if defined? mod::Boolean
|
57
|
+
mod.const_set('Boolean', Virtus::Attribute::Boolean)
|
58
|
+
end
|
59
|
+
|
54
60
|
def inject_api_helpers_to_mod(mod, &_block)
|
55
61
|
mod.extend(BaseHelper)
|
56
62
|
yield if block_given?
|
@@ -75,9 +81,8 @@ module Grape
|
|
75
81
|
protected
|
76
82
|
|
77
83
|
def process_named_params
|
78
|
-
|
79
|
-
|
80
|
-
end
|
84
|
+
return unless @named_params && @named_params.any?
|
85
|
+
api.namespace_stackable(:named_params, @named_params)
|
81
86
|
end
|
82
87
|
end
|
83
88
|
end
|
@@ -6,57 +6,74 @@ module Grape
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
include Grape::DSL::Settings
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
|
12
|
-
# namespaces.
|
13
|
-
#
|
14
|
-
# @param params [Hash] The initial hash to filter. Usually this will just be `params`
|
15
|
-
# @param options [Hash] Can pass `:include_missing`, `:stringify` and `:include_parent_namespaces`
|
16
|
-
# options. `:include_parent_namespaces` defaults to true, hence must be set to false if
|
17
|
-
# you want only to return params declared against the current/target endpoint.
|
18
|
-
def declared(params, options = {}, declared_params = nil)
|
19
|
-
options[:include_missing] = true unless options.key?(:include_missing)
|
20
|
-
options[:include_parent_namespaces] = true unless options.key?(:include_parent_namespaces)
|
21
|
-
|
22
|
-
if declared_params.nil?
|
23
|
-
declared_params = (!options[:include_parent_namespaces] ? route_setting(:declared_params) :
|
24
|
-
(route_setting(:saved_declared_params) || [])).flatten(1) || []
|
25
|
-
end
|
9
|
+
# Denotes a situation where a DSL method has been invoked in a
|
10
|
+
# filter which it should not yet be available in
|
11
|
+
class MethodNotYetAvailable < StandardError; end
|
26
12
|
|
27
|
-
|
28
|
-
|
29
|
-
|
13
|
+
# @param type [Symbol] The type of filter for which evaluation has been
|
14
|
+
# completed
|
15
|
+
# @return [Module] A module containing method overrides suitable for the
|
16
|
+
# position in the filter evaluation sequence denoted by +type+. This
|
17
|
+
# defaults to an empty module if no overrides are defined for the given
|
18
|
+
# filter +type+.
|
19
|
+
def self.post_filter_methods(type)
|
20
|
+
@post_filter_modules ||= { before: PostBeforeFilter }
|
21
|
+
@post_filter_modules[type]
|
22
|
+
end
|
30
23
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
declared_params.inject(Hashie::Mash.new) do |hash, key|
|
37
|
-
key = { key => nil } unless key.is_a? Hash
|
24
|
+
# Methods which should not be available in filters until the before filter
|
25
|
+
# has completed
|
26
|
+
module PostBeforeFilter
|
27
|
+
def declared(params, options = {}, declared_params = nil)
|
28
|
+
options = options.reverse_merge(include_missing: true, include_parent_namespaces: true)
|
38
29
|
|
39
|
-
|
40
|
-
output_key = options[:stringify] ? parent.to_s : parent.to_sym
|
30
|
+
declared_params ||= (!options[:include_parent_namespaces] ? route_setting(:declared_params) : (route_setting(:saved_declared_params) || [])).flatten(1) || []
|
41
31
|
|
42
|
-
|
32
|
+
fail ArgumentError, 'Tried to filter for declared parameters but none exist.' unless declared_params
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
params[parent]
|
49
|
-
end
|
34
|
+
if params.is_a? Array
|
35
|
+
params.map do |param|
|
36
|
+
declared(param || {}, options, declared_params)
|
50
37
|
end
|
38
|
+
else
|
39
|
+
declared_params.each_with_object(Hashie::Mash.new) do |key, hash|
|
40
|
+
key = { key => nil } unless key.is_a? Hash
|
51
41
|
|
52
|
-
|
42
|
+
key.each_pair do |parent, children|
|
43
|
+
output_key = options[:stringify] ? parent.to_s : parent.to_sym
|
44
|
+
|
45
|
+
next unless options[:include_missing] || params.key?(parent)
|
46
|
+
|
47
|
+
hash[output_key] = if children
|
48
|
+
children_params = params[parent] || (children.is_a?(Array) ? [] : {})
|
49
|
+
declared(children_params, options, Array(children))
|
50
|
+
else
|
51
|
+
params[parent]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
59
|
+
# A filtering method that will return a hash
|
60
|
+
# consisting only of keys that have been declared by a
|
61
|
+
# `params` statement against the current/target endpoint or parent
|
62
|
+
# namespaces.
|
63
|
+
#
|
64
|
+
# @see +PostBeforeFilter#declared+
|
65
|
+
#
|
66
|
+
# @param params [Hash] The initial hash to filter. Usually this will just be `params`
|
67
|
+
# @param options [Hash] Can pass `:include_missing`, `:stringify` and `:include_parent_namespaces`
|
68
|
+
# options. `:include_parent_namespaces` defaults to true, hence must be set to false if
|
69
|
+
# you want only to return params declared against the current/target endpoint.
|
70
|
+
def declared(*)
|
71
|
+
fail MethodNotYetAvailable, '#declared is not available prior to parameter validation.'
|
72
|
+
end
|
73
|
+
|
57
74
|
# The API version as specified in the URL.
|
58
75
|
def version
|
59
|
-
env[
|
76
|
+
env[Grape::Env::API_VERSION]
|
60
77
|
end
|
61
78
|
|
62
79
|
# End the request and display an error to the
|
@@ -74,19 +91,25 @@ module Grape
|
|
74
91
|
# @param url [String] The url to be redirect.
|
75
92
|
# @param options [Hash] The options used when redirect.
|
76
93
|
# :permanent, default false.
|
94
|
+
# :body, default a short message including the URL.
|
77
95
|
def redirect(url, options = {})
|
78
|
-
|
79
|
-
|
96
|
+
permanent = options.fetch(:permanent, false)
|
97
|
+
body_message = options.fetch(:body, nil)
|
98
|
+
if permanent
|
80
99
|
status 301
|
100
|
+
body_message ||= "This resource has been moved permanently to #{url}."
|
81
101
|
else
|
82
102
|
if env[Grape::Http::Headers::HTTP_VERSION] == 'HTTP/1.1' && request.request_method.to_s.upcase != Grape::Http::Headers::GET
|
83
103
|
status 303
|
104
|
+
body_message ||= "An alternate resource is located at #{url}."
|
84
105
|
else
|
85
106
|
status 302
|
107
|
+
body_message ||= "This resource has been moved temporarily to #{url}."
|
86
108
|
end
|
87
109
|
end
|
88
110
|
header 'Location', url
|
89
|
-
|
111
|
+
content_type 'text/plain'
|
112
|
+
body body_message
|
90
113
|
end
|
91
114
|
|
92
115
|
# Set or retrieve the HTTP status code.
|
@@ -241,7 +264,7 @@ module Grape
|
|
241
264
|
if key
|
242
265
|
representation = (@body || {}).merge(key => representation)
|
243
266
|
elsif entity_class.present? && @body
|
244
|
-
fail ArgumentError, "Representation of type #{representation.class} cannot be merged." unless representation.respond_to?(
|
267
|
+
fail ArgumentError, "Representation of type #{representation.class} cannot be merged." unless representation.respond_to?(:merge)
|
245
268
|
representation = @body.merge(representation)
|
246
269
|
end
|
247
270
|
|
@@ -257,7 +280,7 @@ module Grape
|
|
257
280
|
# route.route_description
|
258
281
|
# end
|
259
282
|
def route
|
260
|
-
env[
|
283
|
+
env[Grape::Env::RACK_ROUTING_ARGS][:route_info]
|
261
284
|
end
|
262
285
|
|
263
286
|
# Attempt to locate the Entity class for a given object, if not given
|
@@ -293,7 +316,7 @@ module Grape
|
|
293
316
|
# the given entity_class.
|
294
317
|
def entity_representation_for(entity_class, object, options)
|
295
318
|
embeds = { env: env }
|
296
|
-
embeds[:version] = env[
|
319
|
+
embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION]
|
297
320
|
entity_class.represent(object, embeds.merge(options))
|
298
321
|
end
|
299
322
|
end
|