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.

Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +9 -4
  3. data/CHANGELOG.md +265 -215
  4. data/CONTRIBUTING.md +4 -4
  5. data/Gemfile +0 -1
  6. data/Gemfile.lock +166 -0
  7. data/README.md +426 -161
  8. data/RELEASING.md +14 -6
  9. data/Rakefile +30 -33
  10. data/UPGRADING.md +54 -23
  11. data/benchmark/simple.rb +27 -0
  12. data/gemfiles/rack_1.5.2.gemfile +13 -0
  13. data/gemfiles/rails_3.gemfile +2 -2
  14. data/gemfiles/rails_4.gemfile +1 -2
  15. data/grape.gemspec +6 -7
  16. data/lib/grape/api.rb +24 -4
  17. data/lib/grape/dsl/callbacks.rb +20 -0
  18. data/lib/grape/dsl/configuration.rb +59 -2
  19. data/lib/grape/dsl/helpers.rb +8 -3
  20. data/lib/grape/dsl/inside_route.rb +100 -45
  21. data/lib/grape/dsl/parameters.rb +96 -7
  22. data/lib/grape/dsl/request_response.rb +1 -1
  23. data/lib/grape/dsl/routing.rb +17 -4
  24. data/lib/grape/dsl/settings.rb +36 -1
  25. data/lib/grape/dsl/validations.rb +7 -5
  26. data/lib/grape/endpoint.rb +102 -57
  27. data/lib/grape/error_formatter/base.rb +6 -6
  28. data/lib/grape/exceptions/base.rb +5 -5
  29. data/lib/grape/exceptions/invalid_version_header.rb +10 -0
  30. data/lib/grape/exceptions/unknown_parameter.rb +10 -0
  31. data/lib/grape/exceptions/validation_errors.rb +4 -3
  32. data/lib/grape/formatter/serializable_hash.rb +3 -2
  33. data/lib/grape/http/headers.rb +0 -1
  34. data/lib/grape/locale/en.yml +5 -1
  35. data/lib/grape/middleware/auth/base.rb +2 -2
  36. data/lib/grape/middleware/auth/dsl.rb +1 -1
  37. data/lib/grape/middleware/auth/strategies.rb +1 -1
  38. data/lib/grape/middleware/base.rb +8 -4
  39. data/lib/grape/middleware/error.rb +3 -2
  40. data/lib/grape/middleware/filter.rb +1 -1
  41. data/lib/grape/middleware/formatter.rb +64 -45
  42. data/lib/grape/middleware/globals.rb +3 -3
  43. data/lib/grape/middleware/versioner/accept_version_header.rb +5 -7
  44. data/lib/grape/middleware/versioner/header.rb +113 -50
  45. data/lib/grape/middleware/versioner/param.rb +5 -8
  46. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +20 -0
  47. data/lib/grape/middleware/versioner/path.rb +3 -6
  48. data/lib/grape/namespace.rb +13 -2
  49. data/lib/grape/path.rb +4 -3
  50. data/lib/grape/request.rb +40 -0
  51. data/lib/grape/route.rb +5 -0
  52. data/lib/grape/util/content_types.rb +9 -9
  53. data/lib/grape/util/env.rb +22 -0
  54. data/lib/grape/util/file_response.rb +21 -0
  55. data/lib/grape/util/inheritable_setting.rb +23 -2
  56. data/lib/grape/util/inheritable_values.rb +1 -1
  57. data/lib/grape/util/stackable_values.rb +5 -2
  58. data/lib/grape/util/strict_hash_configuration.rb +2 -1
  59. data/lib/grape/validations/attributes_iterator.rb +8 -3
  60. data/lib/grape/validations/params_scope.rb +164 -22
  61. data/lib/grape/validations/types/build_coercer.rb +53 -0
  62. data/lib/grape/validations/types/custom_type_coercer.rb +183 -0
  63. data/lib/grape/validations/types/file.rb +28 -0
  64. data/lib/grape/validations/types/json.rb +65 -0
  65. data/lib/grape/validations/types/multiple_type_coercer.rb +76 -0
  66. data/lib/grape/validations/types/variant_collection_coercer.rb +59 -0
  67. data/lib/grape/validations/types/virtus_collection_patch.rb +16 -0
  68. data/lib/grape/validations/types.rb +144 -0
  69. data/lib/grape/validations/validators/all_or_none.rb +1 -1
  70. data/lib/grape/validations/validators/allow_blank.rb +3 -3
  71. data/lib/grape/validations/validators/base.rb +7 -0
  72. data/lib/grape/validations/validators/coerce.rb +32 -34
  73. data/lib/grape/validations/validators/presence.rb +2 -3
  74. data/lib/grape/validations/validators/regexp.rb +2 -4
  75. data/lib/grape/validations/validators/values.rb +3 -3
  76. data/lib/grape/validations.rb +5 -0
  77. data/lib/grape/version.rb +2 -1
  78. data/lib/grape.rb +15 -12
  79. data/pkg/grape-0.13.0.gem +0 -0
  80. data/spec/grape/api/custom_validations_spec.rb +5 -4
  81. data/spec/grape/api/deeply_included_options_spec.rb +7 -7
  82. data/spec/grape/api/nested_helpers_spec.rb +4 -2
  83. data/spec/grape/api/shared_helpers_spec.rb +8 -8
  84. data/spec/grape/api_spec.rb +151 -54
  85. data/spec/grape/dsl/configuration_spec.rb +13 -0
  86. data/spec/grape/dsl/helpers_spec.rb +16 -2
  87. data/spec/grape/dsl/inside_route_spec.rb +40 -4
  88. data/spec/grape/dsl/parameters_spec.rb +0 -6
  89. data/spec/grape/dsl/routing_spec.rb +1 -1
  90. data/spec/grape/dsl/validations_spec.rb +18 -0
  91. data/spec/grape/endpoint_spec.rb +130 -6
  92. data/spec/grape/entity_spec.rb +10 -8
  93. data/spec/grape/exceptions/invalid_accept_header_spec.rb +1 -15
  94. data/spec/grape/exceptions/validation_errors_spec.rb +28 -0
  95. data/spec/grape/integration/rack_spec.rb +3 -2
  96. data/spec/grape/middleware/base_spec.rb +40 -16
  97. data/spec/grape/middleware/error_spec.rb +16 -15
  98. data/spec/grape/middleware/exception_spec.rb +45 -43
  99. data/spec/grape/middleware/formatter_spec.rb +34 -5
  100. data/spec/grape/middleware/versioner/header_spec.rb +79 -47
  101. data/spec/grape/path_spec.rb +10 -10
  102. data/spec/grape/presenters/presenter_spec.rb +2 -2
  103. data/spec/grape/request_spec.rb +100 -0
  104. data/spec/grape/util/inheritable_values_spec.rb +14 -0
  105. data/spec/grape/util/stackable_values_spec.rb +10 -0
  106. data/spec/grape/validations/params_scope_spec.rb +86 -0
  107. data/spec/grape/validations/types_spec.rb +95 -0
  108. data/spec/grape/validations/validators/coerce_spec.rb +364 -10
  109. data/spec/grape/validations/validators/values_spec.rb +27 -15
  110. data/spec/grape/validations_spec.rb +53 -24
  111. data/spec/shared/versioning_examples.rb +2 -2
  112. data/spec/spec_helper.rb +0 -1
  113. data/spec/support/versioned_helpers.rb +2 -2
  114. metadata +55 -14
  115. data/.gitignore +0 -46
  116. data/.rspec +0 -2
  117. data/.rubocop.yml +0 -7
  118. data/.rubocop_todo.yml +0 -84
  119. data/.travis.yml +0 -20
  120. data/.yardopts +0 -2
  121. data/lib/backports/active_support/deep_dup.rb +0 -49
  122. data/lib/backports/active_support/duplicable.rb +0 -88
  123. 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/intridea/grape) for all supported platforms.
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 Intridea repository](https://github.com/intridea/grape) generally have large Grape-based projects. Point one to Grape HEAD and run all your API tests to catch any obvious regressions.
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: 'intridea/grape'
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/intridea/grape/blob/v0.6.0/README.md).
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 release."
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
- begin
26
- require 'yard'
27
- DOC_FILES = ['lib/**/*.rb', 'README.md']
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
- YARD::Rake::YardocTask.new(:doc) do |t|
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 :doc do
34
- YARD::Rake::YardocTask.new(:pages) do |t|
35
- t.files = DOC_FILES
36
- t.options = ['-o', '../grape.doc/docs']
37
- end
38
-
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: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
- 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')
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/intridea/grape/pull/1029) for more information.
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/intridea/grape/issues/1023).
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/intridea/grape/pull/957) for more information.
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/intridea/grape/issues/889) for more information.
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/intridea/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:
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/intridea/grape/pull/1001) and [#914](https://github.com/intridea/grape/issues/914) for more info.
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/intridea/grape/issues/559) for more information.
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/intridea/grape/pull/879) for more information.
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/intridea/grape/pull/901) for more information.
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/intridea/grape/pull/886) for more information.
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/intridea/grape/pull/864) for more information.
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/intridea/grape/issues/836).
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/intridea/grape#custom-validators) in the documentation.
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/intridea/grape#api-formats) and [#809](https://github.com/intridea/grape/pull/809) for more info.
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/intridea/grape/issues/801) for more information.
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/intridea/grape/issues/898) for more information.
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/intridea/grape/tree/v0.7.0/lib/grape/middleware/auth)
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/intridea/Grape/pull/703) for more information.
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/intridea/grape/pull/544) for more information.
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/intridea/Grape/pull/525) for more information.
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/intridea/Grape/issues/543).
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/intridea/Grape/pull/545) for more information.
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/intridea/grape/issues/462).
581
+ For more information see [#462](https://github.com/ruby-grape/grape/issues/462).
@@ -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
@@ -0,0 +1,13 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rack', '1.5.2'
6
+
7
+ group :development, :test do
8
+ gem 'guard'
9
+ gem 'guard-rspec'
10
+ gem 'guard-rubocop'
11
+ end
12
+
13
+ gemspec path: '../'
@@ -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 :path => '../'
14
+ gemspec path: '../'
@@ -5,10 +5,9 @@ source 'https://rubygems.org'
5
5
  gem 'rails', '4.1.6'
6
6
 
7
7
  group :development, :test do
8
- gem 'rubocop', '~> 0.31.0'
9
8
  gem 'guard'
10
9
  gem 'guard-rspec'
11
10
  gem 'guard-rubocop'
12
11
  end
13
12
 
14
- gemspec :path => '../'
13
+ gemspec path: '../'
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/intridea/grape'
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 = `git ls-files`.split("\n")
40
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
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
- # creating Grape APIs.Users should subclass this
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 name [Symbol] Purely placebo, just allows to name the scope to make the code more readable.
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
 
@@ -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