grape 0.12.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 +265 -215
- data/CONTRIBUTING.md +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +166 -0
- data/README.md +426 -161
- data/RELEASING.md +14 -6
- data/Rakefile +30 -33
- data/UPGRADING.md +54 -23
- 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 +6 -7
- data/lib/grape/api.rb +24 -4
- data/lib/grape/dsl/callbacks.rb +20 -0
- data/lib/grape/dsl/configuration.rb +59 -2
- data/lib/grape/dsl/helpers.rb +8 -3
- data/lib/grape/dsl/inside_route.rb +100 -45
- data/lib/grape/dsl/parameters.rb +96 -7
- data/lib/grape/dsl/request_response.rb +1 -1
- data/lib/grape/dsl/routing.rb +17 -4
- data/lib/grape/dsl/settings.rb +36 -1
- data/lib/grape/dsl/validations.rb +7 -5
- data/lib/grape/endpoint.rb +102 -57
- 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/exceptions/unknown_parameter.rb +10 -0
- data/lib/grape/exceptions/validation_errors.rb +4 -3
- data/lib/grape/formatter/serializable_hash.rb +3 -2
- data/lib/grape/http/headers.rb +0 -1
- data/lib/grape/locale/en.yml +5 -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 +8 -4
- data/lib/grape/middleware/error.rb +3 -2
- data/lib/grape/middleware/filter.rb +1 -1
- data/lib/grape/middleware/formatter.rb +64 -45
- 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/namespace.rb +13 -2
- data/lib/grape/path.rb +4 -3
- data/lib/grape/request.rb +40 -0
- data/lib/grape/route.rb +5 -0
- data/lib/grape/util/content_types.rb +9 -9
- data/lib/grape/util/env.rb +22 -0
- data/lib/grape/util/file_response.rb +21 -0
- data/lib/grape/util/inheritable_setting.rb +23 -2
- data/lib/grape/util/inheritable_values.rb +1 -1
- data/lib/grape/util/stackable_values.rb +5 -2
- 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 +164 -22
- 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/types.rb +144 -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 +32 -34
- 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/validations.rb +5 -0
- data/lib/grape/version.rb +2 -1
- data/lib/grape.rb +15 -12
- 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 +151 -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 +40 -4
- data/spec/grape/dsl/parameters_spec.rb +0 -6
- data/spec/grape/dsl/routing_spec.rb +1 -1
- data/spec/grape/dsl/validations_spec.rb +18 -0
- data/spec/grape/endpoint_spec.rb +130 -6
- data/spec/grape/entity_spec.rb +10 -8
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +1 -15
- data/spec/grape/exceptions/validation_errors_spec.rb +28 -0
- data/spec/grape/integration/rack_spec.rb +3 -2
- data/spec/grape/middleware/base_spec.rb +40 -16
- 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 -5
- 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/util/inheritable_values_spec.rb +14 -0
- data/spec/grape/util/stackable_values_spec.rb +10 -0
- data/spec/grape/validations/params_scope_spec.rb +86 -0
- data/spec/grape/validations/types_spec.rb +95 -0
- data/spec/grape/validations/validators/coerce_spec.rb +364 -10
- data/spec/grape/validations/validators/values_spec.rb +27 -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 +55 -14
- 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/backports/active_support/deep_dup.rb +0 -49
- data/lib/backports/active_support/duplicable.rb +0 -88
- data/lib/grape/http/request.rb +0 -27
data/RELEASING.md
CHANGED
@@ -12,12 +12,12 @@ bundle install
|
|
12
12
|
rake
|
13
13
|
```
|
14
14
|
|
15
|
-
Check that the last build succeeded in [Travis CI](https://travis-ci.org/
|
15
|
+
Check that the last build succeeded in [Travis CI](https://travis-ci.org/ruby-grape/grape) for all supported platforms.
|
16
16
|
|
17
|
-
Those with r/w permissions to the [master
|
17
|
+
Those with r/w permissions to the [master Grape repository](https://github.com/ruby-grape/grape) generally have large Grape-based projects. Point one to Grape HEAD and run all your API tests to catch any obvious regressions.
|
18
18
|
|
19
19
|
```
|
20
|
-
gem grape, github: '
|
20
|
+
gem grape, github: 'ruby-grape/grape'
|
21
21
|
```
|
22
22
|
|
23
23
|
Increment the version, modify [lib/grape/version.rb](lib/grape/version.rb).
|
@@ -69,7 +69,7 @@ Modify the "Stable Release" section in [README.md](README.md). Change the text t
|
|
69
69
|
## Stable Release
|
70
70
|
|
71
71
|
You're reading the documentation for the next release of Grape, which should be 0.6.1.
|
72
|
-
The current stable release is [0.6.0](https://github.com/
|
72
|
+
The current stable release is [0.6.0](https://github.com/ruby-grape/grape/blob/v0.6.0/README.md).
|
73
73
|
```
|
74
74
|
|
75
75
|
Add the next release to [CHANGELOG.md](CHANGELOG.md).
|
@@ -81,11 +81,19 @@ Next Release
|
|
81
81
|
* Your contribution here.
|
82
82
|
```
|
83
83
|
|
84
|
+
Bump the minor version in lib/grape/version.rb.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
module Grape
|
88
|
+
VERSION = '0.6.1'
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
84
92
|
Comit your changes.
|
85
93
|
|
86
94
|
```
|
87
|
-
git add CHANGELOG.md README.md
|
88
|
-
git commit -m "Preparing for next
|
95
|
+
git add CHANGELOG.md README.md lib/grape/version.rb
|
96
|
+
git commit -m "Preparing for next development iteration, 0.6.1."
|
89
97
|
git push origin master
|
90
98
|
```
|
91
99
|
|
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:intridea/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
|
@@ -29,13 +60,13 @@ class CacheBusterMiddleware < Grape::Middleware::Base
|
|
29
60
|
end
|
30
61
|
```
|
31
62
|
|
32
|
-
See [#1029](https://github.com/
|
63
|
+
See [#1029](https://github.com/ruby-grape/grape/pull/1029) for more information.
|
33
64
|
|
34
65
|
#### Changes in present
|
35
66
|
|
36
67
|
Using `present` with objects that responded to `merge` would cause early evaluation of the represented object, with unexpected side-effects, such as missing parameters or environment within rendering code. Grape now only merges represented objects with a previously rendered body, usually when multiple `present` calls are made in the same route.
|
37
68
|
|
38
|
-
See [grape-with-roar#5](https://github.com/dblock/grape-with-roar/issues/5) and [#1023](https://github.com/
|
69
|
+
See [grape-with-roar#5](https://github.com/dblock/grape-with-roar/issues/5) and [#1023](https://github.com/ruby-grape/grape/issues/1023).
|
39
70
|
|
40
71
|
#### Changes to regexp validator
|
41
72
|
|
@@ -47,7 +78,7 @@ params do
|
|
47
78
|
end
|
48
79
|
```
|
49
80
|
|
50
|
-
See [#957](https://github.com/
|
81
|
+
See [#957](https://github.com/ruby-grape/grape/pull/957) for more information.
|
51
82
|
|
52
83
|
#### Replace error_response with error! in rescue_from blocks
|
53
84
|
|
@@ -88,11 +119,11 @@ Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finis
|
|
88
119
|
error!(e)
|
89
120
|
```
|
90
121
|
|
91
|
-
See [#889](https://github.com/
|
122
|
+
See [#889](https://github.com/ruby-grape/grape/issues/889) for more information.
|
92
123
|
|
93
124
|
#### Changes to routes when using `format`
|
94
125
|
|
95
|
-
Version 0.10.0 has introduced a change via [#809](https://github.com/
|
126
|
+
Version 0.10.0 has introduced a change via [#809](https://github.com/ruby-grape/grape/pull/809) whereas routes no longer got file-type suffixes added if you declared a single API `format`. This has been reverted, it's now again possible to call API with proper suffix when single `format` is defined:
|
96
127
|
|
97
128
|
```ruby
|
98
129
|
class API < Grape::API
|
@@ -108,7 +139,7 @@ Will respond with JSON to `/hello` **and** `/hello.json`.
|
|
108
139
|
|
109
140
|
Will respond with 404 to `/hello.xml`, `/hello.txt` etc.
|
110
141
|
|
111
|
-
See the [#1001](https://github.com/
|
142
|
+
See the [#1001](https://github.com/ruby-grape/grape/pull/1001) and [#914](https://github.com/ruby-grape/grape/issues/914) for more info.
|
112
143
|
|
113
144
|
### Upgrading to >= 0.11.0
|
114
145
|
|
@@ -120,20 +151,20 @@ Grape now supports, but doesn't require Rack 1.6.0. If you encounter an issue wi
|
|
120
151
|
gem 'rack', '~> 1.6.0'
|
121
152
|
```
|
122
153
|
|
123
|
-
See [#559](https://github.com/
|
154
|
+
See [#559](https://github.com/ruby-grape/grape/issues/559) for more information.
|
124
155
|
|
125
156
|
#### Removed route_info
|
126
157
|
|
127
158
|
Key route_info is excluded from params.
|
128
159
|
|
129
|
-
See [#879](https://github.com/
|
160
|
+
See [#879](https://github.com/ruby-grape/grape/pull/879) for more information.
|
130
161
|
|
131
162
|
|
132
163
|
#### Fix callbacks within a version block
|
133
164
|
|
134
165
|
Callbacks defined in a version block are only called for the routes defined in that block. This was a regression introduced in Grape 0.10.0, and is fixed in this version.
|
135
166
|
|
136
|
-
See [#901](https://github.com/
|
167
|
+
See [#901](https://github.com/ruby-grape/grape/pull/901) for more information.
|
137
168
|
|
138
169
|
|
139
170
|
#### Make type of group of parameters required
|
@@ -141,7 +172,7 @@ See [#901](https://github.com/intridea/grape/pull/901) for more information.
|
|
141
172
|
Groups of parameters now require their type to be set explicitly as Array or Hash.
|
142
173
|
Not setting the type now results in MissingGroupTypeError, unsupported type will raise UnsupportedTypeError.
|
143
174
|
|
144
|
-
See [#886](https://github.com/
|
175
|
+
See [#886](https://github.com/ruby-grape/grape/pull/886) for more information.
|
145
176
|
|
146
177
|
### Upgrading to >= 0.10.1
|
147
178
|
|
@@ -149,7 +180,7 @@ See [#886](https://github.com/intridea/grape/pull/886) for more information.
|
|
149
180
|
|
150
181
|
Attributes with `nil` values or with values that evaluate to `false` are no longer considered *missing* and will be returned when `include_missing` is set to `false`.
|
151
182
|
|
152
|
-
See [#864](https://github.com/
|
183
|
+
See [#864](https://github.com/ruby-grape/grape/pull/864) for more information.
|
153
184
|
|
154
185
|
### Upgrading to >= 0.10.0
|
155
186
|
|
@@ -284,13 +315,13 @@ get do
|
|
284
315
|
end
|
285
316
|
```
|
286
317
|
|
287
|
-
For more information see [#836](https://github.com/
|
318
|
+
For more information see [#836](https://github.com/ruby-grape/grape/issues/836).
|
288
319
|
|
289
320
|
#### Changes to Custom Validators
|
290
321
|
|
291
322
|
To implement a custom validator, you need to inherit from `Grape::Validations::Base` instead of `Grape::Validations::Validator`.
|
292
323
|
|
293
|
-
For more information see [Custom Validators](https://github.com/
|
324
|
+
For more information see [Custom Validators](https://github.com/ruby-grape/grape#custom-validators) in the documentation.
|
294
325
|
|
295
326
|
#### Changes to Raising Grape::Exceptions::Validation
|
296
327
|
|
@@ -337,7 +368,7 @@ class API < Grape::API
|
|
337
368
|
end
|
338
369
|
```
|
339
370
|
|
340
|
-
See the [the updated API Formats documentation](https://github.com/
|
371
|
+
See the [the updated API Formats documentation](https://github.com/ruby-grape/grape#api-formats) and [#809](https://github.com/ruby-grape/grape/pull/809) for more info.
|
341
372
|
|
342
373
|
#### Changes to Evaluation of Permitted Parameter Values
|
343
374
|
|
@@ -357,7 +388,7 @@ params do
|
|
357
388
|
end
|
358
389
|
```
|
359
390
|
|
360
|
-
See [#801](https://github.com/
|
391
|
+
See [#801](https://github.com/ruby-grape/grape/issues/801) for more information.
|
361
392
|
|
362
393
|
#### Changes to version
|
363
394
|
|
@@ -389,7 +420,7 @@ end
|
|
389
420
|
|
390
421
|
when making a API call `GET /foo/v2/1`, the API would set instance variable `@output` to `hello1-v2`
|
391
422
|
|
392
|
-
See [#898](https://github.com/
|
423
|
+
See [#898](https://github.com/ruby-grape/grape/issues/898) for more information.
|
393
424
|
|
394
425
|
|
395
426
|
### Upgrading to >= 0.9.0
|
@@ -422,10 +453,10 @@ As replacement can be used
|
|
422
453
|
* `Grape::Middleware::Auth::Digest` => [`Rack::Auth::Digest::MD5`](https://github.com/rack/rack/blob/master/lib/rack/auth/digest/md5.rb)
|
423
454
|
* `Grape::Middleware::Auth::OAuth2` => [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2)
|
424
455
|
|
425
|
-
If this is not possible you can extract the middleware files from [grape v0.7.0](https://github.com/
|
456
|
+
If this is not possible you can extract the middleware files from [grape v0.7.0](https://github.com/ruby-grape/grape/tree/v0.7.0/lib/grape/middleware/auth)
|
426
457
|
and host these files within your application
|
427
458
|
|
428
|
-
See [#703](https://github.com/
|
459
|
+
See [#703](https://github.com/ruby-grape/Grape/pull/703) for more information.
|
429
460
|
|
430
461
|
### Upgrading to >= 0.7.0
|
431
462
|
|
@@ -462,7 +493,7 @@ rescue_from ParentError, rescue_subclasses: false do |e|
|
|
462
493
|
end
|
463
494
|
```
|
464
495
|
|
465
|
-
See [#544](https://github.com/
|
496
|
+
See [#544](https://github.com/ruby-grape/grape/pull/544) for more information.
|
466
497
|
|
467
498
|
|
468
499
|
#### Changes in the Default HTTP Status Code
|
@@ -485,7 +516,7 @@ You may also use `default_error_status` to change the global default.
|
|
485
516
|
default_error_status 400
|
486
517
|
```
|
487
518
|
|
488
|
-
See [#525](https://github.com/
|
519
|
+
See [#525](https://github.com/ruby-grape/Grape/pull/525) for more information.
|
489
520
|
|
490
521
|
|
491
522
|
#### Changes in Parameter Declaration and Validation
|
@@ -502,7 +533,7 @@ params do
|
|
502
533
|
end
|
503
534
|
```
|
504
535
|
|
505
|
-
This caused the ambiguity and unexpected errors described in [#543](https://github.com/
|
536
|
+
This caused the ambiguity and unexpected errors described in [#543](https://github.com/ruby-grape/Grape/issues/543).
|
506
537
|
|
507
538
|
In Grape 0.7.0, the `group`, `optional` and `requires` keywords take an additional `type` attribute which defaults to `Array`. This means that without a `type` attribute, these nested parameters will no longer accept a single hash, only an array (of hashes).
|
508
539
|
|
@@ -530,7 +561,7 @@ params do
|
|
530
561
|
end
|
531
562
|
```
|
532
563
|
|
533
|
-
See [#545](https://github.com/
|
564
|
+
See [#545](https://github.com/ruby-grape/Grape/pull/545) for more information.
|
534
565
|
|
535
566
|
|
536
567
|
### Upgrading to 0.6.0
|
@@ -547,4 +578,4 @@ rescue_from Grape::Exceptions::Validations do |e|
|
|
547
578
|
end
|
548
579
|
```
|
549
580
|
|
550
|
-
For more information see [#462](https://github.com/
|
581
|
+
For more information see [#462](https://github.com/ruby-grape/grape/issues/462).
|
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
@@ -7,13 +7,11 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ['Michael Bleigh']
|
9
9
|
s.email = ['michael@intridea.com']
|
10
|
-
s.homepage = 'https://github.com/
|
10
|
+
s.homepage = 'https://github.com/ruby-grape/grape'
|
11
11
|
s.summary = 'A simple Ruby framework for building REST-like APIs.'
|
12
12
|
s.description = 'A Ruby framework for rapid API development with great conventions.'
|
13
13
|
s.license = 'MIT'
|
14
14
|
|
15
|
-
s.rubyforge_project = 'grape'
|
16
|
-
|
17
15
|
s.add_runtime_dependency 'rack', '>= 1.3.0'
|
18
16
|
s.add_runtime_dependency 'rack-mount'
|
19
17
|
s.add_runtime_dependency 'rack-accept'
|
@@ -33,11 +31,12 @@ Gem::Specification.new do |s|
|
|
33
31
|
s.add_development_dependency 'bundler'
|
34
32
|
s.add_development_dependency 'cookiejar'
|
35
33
|
s.add_development_dependency 'rack-contrib'
|
36
|
-
s.add_development_dependency 'mime-types'
|
34
|
+
s.add_development_dependency 'mime-types', '< 3.0'
|
37
35
|
s.add_development_dependency 'appraisal'
|
36
|
+
s.add_development_dependency 'benchmark-ips'
|
37
|
+
s.add_development_dependency 'rubocop', '0.35.1'
|
38
38
|
|
39
|
-
s.files =
|
40
|
-
s.test_files =
|
41
|
-
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/**/*']
|
42
41
|
s.require_paths = ['lib']
|
43
42
|
end
|
data/lib/grape/api.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Grape
|
2
|
-
# The API class is the primary entry point for
|
3
|
-
#
|
4
|
-
# class in order to build an API.
|
2
|
+
# The API class is the primary entry point for creating Grape APIs. Users
|
3
|
+
# should subclass this class in order to build an API.
|
5
4
|
class API
|
6
5
|
include Grape::DSL::API
|
7
6
|
|
8
7
|
class << self
|
9
8
|
attr_reader :instance
|
9
|
+
|
10
|
+
# A class-level lock to ensure the API is not compiled by multiple
|
11
|
+
# threads simultaneously within the same process.
|
10
12
|
LOCK = Mutex.new
|
11
13
|
|
14
|
+
# Clears all defined routes, endpoints, etc., on this API.
|
12
15
|
def reset!
|
13
16
|
@route_set = Rack::Mount::RouteSet.new
|
14
17
|
@endpoints = []
|
@@ -16,32 +19,42 @@ module Grape
|
|
16
19
|
reset_validations!
|
17
20
|
end
|
18
21
|
|
22
|
+
# Parses the API's definition and compiles it into an instance of
|
23
|
+
# Grape::API.
|
19
24
|
def compile
|
20
25
|
@instance ||= new
|
21
26
|
end
|
22
27
|
|
28
|
+
# Wipe the compiled API so we can recompile after changes were made.
|
23
29
|
def change!
|
24
30
|
@instance = nil
|
25
31
|
end
|
26
32
|
|
33
|
+
# This is the interface point between Rack and Grape; it accepts a request
|
34
|
+
# from Rack and ultimately returns an array of three values: the status,
|
35
|
+
# the headers, and the body. See [the rack specification]
|
36
|
+
# (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
|
27
37
|
def call(env)
|
28
38
|
LOCK.synchronize { compile } unless instance
|
29
39
|
call!(env)
|
30
40
|
end
|
31
41
|
|
42
|
+
# A non-synchronized version of ::call.
|
32
43
|
def call!(env)
|
33
44
|
instance.call(env)
|
34
45
|
end
|
35
46
|
|
36
47
|
# Create a scope without affecting the URL.
|
37
48
|
#
|
38
|
-
# @param
|
49
|
+
# @param _name [Symbol] Purely placebo, just allows to name the scope to
|
50
|
+
# make the code more readable.
|
39
51
|
def scope(_name = nil, &block)
|
40
52
|
within_namespace do
|
41
53
|
nest(block)
|
42
54
|
end
|
43
55
|
end
|
44
56
|
|
57
|
+
# (see #cascade?)
|
45
58
|
def cascade(value = nil)
|
46
59
|
if value.nil?
|
47
60
|
inheritable_setting.namespace_inheritable.keys.include?(:cascade) ? !!namespace_inheritable(:cascade) : true
|
@@ -84,6 +97,8 @@ module Grape
|
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
100
|
+
# Builds the routes from the defined endpoints, effectively compiling
|
101
|
+
# this API into a usable form.
|
87
102
|
def initialize
|
88
103
|
@route_set = Rack::Mount::RouteSet.new
|
89
104
|
add_head_not_allowed_methods_and_options_methods
|
@@ -94,6 +109,7 @@ module Grape
|
|
94
109
|
@route_set.freeze
|
95
110
|
end
|
96
111
|
|
112
|
+
# Handle a request. See Rack documentation for what `env` is.
|
97
113
|
def call(env)
|
98
114
|
result = @route_set.call(env)
|
99
115
|
result[1].delete(Grape::Http::Headers::X_CASCADE) unless cascade?
|
@@ -168,6 +184,8 @@ module Grape
|
|
168
184
|
end
|
169
185
|
end
|
170
186
|
|
187
|
+
# Allows definition of endpoints that ignore the versioning configuration
|
188
|
+
# used by the rest of your API.
|
171
189
|
def without_versioning(&_block)
|
172
190
|
old_version = self.class.namespace_inheritable(:version)
|
173
191
|
old_version_options = self.class.namespace_inheritable(:version_options)
|
@@ -181,6 +199,8 @@ module Grape
|
|
181
199
|
self.class.namespace_inheritable(:version_options, old_version_options)
|
182
200
|
end
|
183
201
|
|
202
|
+
# Allows definition of endpoints that ignore the root prefix used by the
|
203
|
+
# rest of your API.
|
184
204
|
def without_root_prefix(&_block)
|
185
205
|
old_prefix = self.class.namespace_inheritable(:root_prefix)
|
186
206
|
|
data/lib/grape/dsl/callbacks.rb
CHANGED
@@ -2,24 +2,44 @@ require 'active_support/concern'
|
|
2
2
|
|
3
3
|
module Grape
|
4
4
|
module DSL
|
5
|
+
# Blocks can be executed before or after every API call, using `before`, `after`,
|
6
|
+
# `before_validation` and `after_validation`.
|
7
|
+
#
|
8
|
+
# Before and after callbacks execute in the following order:
|
9
|
+
#
|
10
|
+
# 1. `before`
|
11
|
+
# 2. `before_validation`
|
12
|
+
# 3. _validations_
|
13
|
+
# 4. `after_validation`
|
14
|
+
# 5. _the API call_
|
15
|
+
# 6. `after`
|
16
|
+
#
|
17
|
+
# Steps 4, 5 and 6 only happen if validation succeeds.
|
5
18
|
module Callbacks
|
6
19
|
extend ActiveSupport::Concern
|
7
20
|
|
8
21
|
include Grape::DSL::Configuration
|
9
22
|
|
10
23
|
module ClassMethods
|
24
|
+
# Execute the given block before validation, coercion, or any endpoint
|
25
|
+
# code is executed.
|
11
26
|
def before(&block)
|
12
27
|
namespace_stackable(:befores, block)
|
13
28
|
end
|
14
29
|
|
30
|
+
# Execute the given block after `before`, but prior to validation or
|
31
|
+
# coercion.
|
15
32
|
def before_validation(&block)
|
16
33
|
namespace_stackable(:before_validations, block)
|
17
34
|
end
|
18
35
|
|
36
|
+
# Execute the given block after validations and coercions, but before
|
37
|
+
# any endpoint code.
|
19
38
|
def after_validation(&block)
|
20
39
|
namespace_stackable(:after_validations, block)
|
21
40
|
end
|
22
41
|
|
42
|
+
# Execute the given block after the endpoint code has run.
|
23
43
|
def after(&block)
|
24
44
|
namespace_stackable(:afters, block)
|
25
45
|
end
|