grape 0.12.0 → 0.13.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/.rubocop_todo.yml +2 -2
- data/CHANGELOG.md +237 -215
- data/CONTRIBUTING.md +4 -4
- data/README.md +133 -10
- data/RELEASING.md +14 -6
- data/Rakefile +1 -1
- data/UPGRADING.md +23 -23
- data/grape.gemspec +1 -3
- data/lib/grape/api.rb +24 -4
- data/lib/grape/dsl/callbacks.rb +20 -0
- data/lib/grape/dsl/configuration.rb +54 -0
- data/lib/grape/dsl/inside_route.rb +33 -1
- data/lib/grape/dsl/parameters.rb +80 -0
- data/lib/grape/dsl/routing.rb +14 -0
- data/lib/grape/dsl/settings.rb +36 -1
- data/lib/grape/dsl/validations.rb +7 -5
- data/lib/grape/endpoint.rb +42 -32
- data/lib/grape/exceptions/unknown_parameter.rb +10 -0
- data/lib/grape/exceptions/validation_errors.rb +4 -3
- data/lib/grape/http/headers.rb +0 -1
- data/lib/grape/http/request.rb +12 -4
- data/lib/grape/locale/en.yml +1 -0
- data/lib/grape/middleware/base.rb +1 -0
- data/lib/grape/middleware/formatter.rb +39 -23
- data/lib/grape/namespace.rb +13 -2
- data/lib/grape/path.rb +1 -0
- data/lib/grape/route.rb +5 -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/parameter_types.rb +58 -0
- data/lib/grape/util/stackable_values.rb +5 -2
- data/lib/grape/validations/params_scope.rb +83 -9
- data/lib/grape/validations/validators/coerce.rb +11 -2
- data/lib/grape/validations.rb +5 -0
- data/lib/grape/version.rb +2 -1
- data/lib/grape.rb +7 -8
- data/spec/grape/api_spec.rb +63 -0
- data/spec/grape/dsl/inside_route_spec.rb +37 -2
- data/spec/grape/dsl/validations_spec.rb +18 -0
- data/spec/grape/endpoint_spec.rb +83 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +28 -0
- data/spec/grape/middleware/base_spec.rb +33 -11
- data/spec/grape/middleware/formatter_spec.rb +0 -5
- data/spec/grape/util/inheritable_values_spec.rb +14 -0
- data/spec/grape/util/parameter_types_spec.rb +54 -0
- data/spec/grape/util/stackable_values_spec.rb +10 -0
- data/spec/grape/validations/params_scope_spec.rb +84 -0
- data/spec/grape/validations/validators/coerce_spec.rb +29 -8
- data/spec/grape/validations/validators/values_spec.rb +12 -0
- metadata +9 -6
- data/lib/backports/active_support/deep_dup.rb +0 -49
- data/lib/backports/active_support/duplicable.rb +0 -88
data/CONTRIBUTING.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
Contributing to Grape
|
2
2
|
=====================
|
3
3
|
|
4
|
-
Grape is work of [hundreds of contributors](https://github.com/
|
4
|
+
Grape is work of [hundreds of contributors](https://github.com/ruby-grape/grape/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/ruby-grape/grape/pulls), [propose features and discuss issues](https://github.com/ruby-grape/grape/issues). When in doubt, ask a question in the [Grape Google Group](http://groups.google.com/group/ruby-grape).
|
5
5
|
|
6
6
|
#### Fork the Project
|
7
7
|
|
8
|
-
Fork the [project on Github](https://github.com/
|
8
|
+
Fork the [project on Github](https://github.com/ruby-grape/grape) and check out your copy.
|
9
9
|
|
10
10
|
```
|
11
11
|
git clone https://github.com/contributor/grape.git
|
12
12
|
cd grape
|
13
|
-
git remote add upstream https://github.com/
|
13
|
+
git remote add upstream https://github.com/ruby-grape/grape.git
|
14
14
|
```
|
15
15
|
|
16
16
|
#### Create a Topic Branch
|
@@ -102,7 +102,7 @@ git push origin my-feature-branch -f
|
|
102
102
|
Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows.
|
103
103
|
|
104
104
|
```
|
105
|
-
* [#123](https://github.com/
|
105
|
+
* [#123](https://github.com/ruby-grape/grape/pull/123): Reticulated splines - [@contributor](https://github.com/contributor).
|
106
106
|
```
|
107
107
|
|
108
108
|
Amend your previous commit and force push the changes.
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
![grape logo](grape.png)
|
2
2
|
|
3
3
|
[![Gem Version](http://img.shields.io/gem/v/grape.svg)](http://badge.fury.io/rb/grape)
|
4
|
-
[![Build Status](http://img.shields.io/travis/
|
5
|
-
[![Dependency Status](https://gemnasium.com/
|
6
|
-
[![Code Climate](https://codeclimate.com/github/
|
7
|
-
[![Inline docs](http://inch-ci.org/github/
|
4
|
+
[![Build Status](http://img.shields.io/travis/ruby-grape/grape.svg)](https://travis-ci.org/ruby-grape/grape)
|
5
|
+
[![Dependency Status](https://gemnasium.com/ruby-grape/grape.svg)](https://gemnasium.com/ruby-grape/grape)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/ruby-grape/grape.svg)](https://codeclimate.com/github/ruby-grape/grape)
|
7
|
+
[![Inline docs](http://inch-ci.org/github/ruby-grape/grape.svg)](http://inch-ci.org/github/ruby-grape/grape)
|
8
8
|
|
9
9
|
## Table of Contents
|
10
10
|
|
@@ -29,6 +29,9 @@
|
|
29
29
|
- [Declared](#declared)
|
30
30
|
- [Include Missing](#include-missing)
|
31
31
|
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
|
32
|
+
- [Supported Parameter Types](#supported-parameter-types)
|
33
|
+
- [Custom Types](#custom-types)
|
34
|
+
- [Dependent Parameters](#dependent-parameters)
|
32
35
|
- [Built-in Validators](#built-in-validators)
|
33
36
|
- [Namespace Validation and Coercion](#namespace-validation-and-coercion)
|
34
37
|
- [Custom Validators](#custom-validators)
|
@@ -37,6 +40,7 @@
|
|
37
40
|
- [Headers](#headers)
|
38
41
|
- [Routes](#routes)
|
39
42
|
- [Helpers](#helpers)
|
43
|
+
- [Path Helpers](#path-helpers)
|
40
44
|
- [Parameter Documentation](#parameter-documentation)
|
41
45
|
- [Cookies](#cookies)
|
42
46
|
- [HTTP Status Code](#http-status-code)
|
@@ -75,6 +79,8 @@
|
|
75
79
|
- [Reloading in Rack Applications](#reloading-in-rack-applications)
|
76
80
|
- [Reloading in Rails Applications](#reloading-in-rails-applications)
|
77
81
|
- [Performance Monitoring](#performance-monitoring)
|
82
|
+
- [Active Support Instrumentation](#active-support-instrumentation)
|
83
|
+
- [Monitoring Products](#monitoring-products)
|
78
84
|
- [Contributing to Grape](#contributing-to-grape)
|
79
85
|
- [Hacking on Grape](#hacking-on-grape)
|
80
86
|
- [License](#license)
|
@@ -90,13 +96,13 @@ content negotiation, versioning and much more.
|
|
90
96
|
|
91
97
|
## Stable Release
|
92
98
|
|
93
|
-
You're reading the documentation for the stable release of Grape 0.
|
99
|
+
You're reading the documentation for the stable release of Grape, 0.13.0.
|
94
100
|
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
95
101
|
|
96
102
|
## Project Resources
|
97
103
|
|
104
|
+
* [Grape Website](http://www.ruby-grape.org)
|
98
105
|
* Need help? [Grape Google Group](http://groups.google.com/group/ruby-grape)
|
99
|
-
* [Grape Wiki](https://github.com/intridea/grape/wiki)
|
100
106
|
|
101
107
|
## Installation
|
102
108
|
|
@@ -729,6 +735,54 @@ params do
|
|
729
735
|
end
|
730
736
|
```
|
731
737
|
|
738
|
+
#### Supported Parameter Types
|
739
|
+
|
740
|
+
The following are all valid types, supported out of the box by Grape:
|
741
|
+
|
742
|
+
* Integer
|
743
|
+
* Float
|
744
|
+
* BigDecimal
|
745
|
+
* Numeric
|
746
|
+
* Date
|
747
|
+
* DateTime
|
748
|
+
* Time
|
749
|
+
* Boolean
|
750
|
+
* String
|
751
|
+
* Symbol
|
752
|
+
* Rack::Multipart::UploadedFile
|
753
|
+
|
754
|
+
#### Custom Types
|
755
|
+
|
756
|
+
Aside from the default set of supported types listed above, any class can be
|
757
|
+
used as a type so long as it defines a class-level `parse` method. This method
|
758
|
+
must take one string argument and return an instance of the correct type, or
|
759
|
+
raise an exception to indicate the value was invalid. E.g.,
|
760
|
+
|
761
|
+
```ruby
|
762
|
+
class Color
|
763
|
+
attr_reader :value
|
764
|
+
def initialize(color)
|
765
|
+
@value = color
|
766
|
+
end
|
767
|
+
|
768
|
+
def self.parse(value)
|
769
|
+
fail 'Invalid color' unless %w(blue red green).include?(value)
|
770
|
+
new(value)
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
# ...
|
775
|
+
|
776
|
+
params do
|
777
|
+
requires :color, type: Color, default: Color.new('blue')
|
778
|
+
end
|
779
|
+
|
780
|
+
get '/stuff' do
|
781
|
+
# params[:color] is already a Color.
|
782
|
+
params[:color].value
|
783
|
+
end
|
784
|
+
```
|
785
|
+
|
732
786
|
#### Validation of Nested Parameters
|
733
787
|
|
734
788
|
Parameters can be nested using `group` or by calling `requires` or `optional` with a block.
|
@@ -752,6 +806,21 @@ params do
|
|
752
806
|
end
|
753
807
|
```
|
754
808
|
|
809
|
+
#### Dependent Parameters
|
810
|
+
|
811
|
+
Suppose some of your parameters are only relevant if another parameter is given;
|
812
|
+
Grape allows you to express this relationship through the `given` method in your
|
813
|
+
parameters block, like so:
|
814
|
+
|
815
|
+
```ruby
|
816
|
+
params do
|
817
|
+
optional :shelf_id, type: Integer
|
818
|
+
given :shelf_id do
|
819
|
+
requires :bin_id, type: Integer
|
820
|
+
end
|
821
|
+
end
|
822
|
+
```
|
823
|
+
|
755
824
|
### Built-in Validators
|
756
825
|
|
757
826
|
#### `allow_blank`
|
@@ -1034,6 +1103,16 @@ subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
|
|
1034
1103
|
end
|
1035
1104
|
```
|
1036
1105
|
|
1106
|
+
`Grape::Exceptions::ValidationErrors#full_messages` returns the validation messages as an array. `Grape::Exceptions::ValidationErrors#message` joins the messages to one string.
|
1107
|
+
|
1108
|
+
For responding with an array of validation messages, you can use `Grape::Exceptions::ValidationErrors#full_messages`.
|
1109
|
+
```ruby
|
1110
|
+
format :json
|
1111
|
+
subject.rescue_from Grape::Exceptions::ValidationErrors do |e|
|
1112
|
+
error!({ messages: e.full_messages }, 400)
|
1113
|
+
end
|
1114
|
+
```
|
1115
|
+
|
1037
1116
|
### I18n
|
1038
1117
|
|
1039
1118
|
Grape supports I18n for parameter-related error messages, but will fallback to English if
|
@@ -1198,6 +1277,10 @@ class API < Grape::API
|
|
1198
1277
|
end
|
1199
1278
|
```
|
1200
1279
|
|
1280
|
+
## Path Helpers
|
1281
|
+
|
1282
|
+
If you need methods for generating paths inside your endpoints, please see the [grape-route-helpers](https://github.com/reprah/grape-route-helpers) gem.
|
1283
|
+
|
1201
1284
|
## Parameter Documentation
|
1202
1285
|
|
1203
1286
|
You can attach additional documentation to `params` using a `documentation` hash.
|
@@ -1339,7 +1422,7 @@ instead of a message.
|
|
1339
1422
|
error!({ error: "unexpected error", detail: "missing widget" }, 500)
|
1340
1423
|
```
|
1341
1424
|
|
1342
|
-
You can present documented errors with a Grape entity using the the [grape-entity](https://github.com/
|
1425
|
+
You can present documented errors with a Grape entity using the the [grape-entity](https://github.com/ruby-grape/grape-entity) gem.
|
1343
1426
|
|
1344
1427
|
```ruby
|
1345
1428
|
module API
|
@@ -1860,8 +1943,8 @@ hash may include `:with`, which defines the entity to expose.
|
|
1860
1943
|
|
1861
1944
|
### Grape Entities
|
1862
1945
|
|
1863
|
-
Add the [grape-entity](https://github.com/
|
1864
|
-
Please refer to the [grape-entity documentation](https://github.com/
|
1946
|
+
Add the [grape-entity](https://github.com/ruby-grape/grape-entity) gem to your Gemfile.
|
1947
|
+
Please refer to the [grape-entity documentation](https://github.com/ruby-grape/grape-entity/blob/master/README.md)
|
1865
1948
|
for more details.
|
1866
1949
|
|
1867
1950
|
The following example exposes statuses.
|
@@ -2023,6 +2106,8 @@ end
|
|
2023
2106
|
Use `body false` to return `204 No Content` without any data or content-type.
|
2024
2107
|
|
2025
2108
|
You can also set the response to a file-like object with `file`.
|
2109
|
+
Note: Rack will read your entire Enumerable before returning a response. If
|
2110
|
+
you would like to stream the response, see `stream`.
|
2026
2111
|
|
2027
2112
|
```ruby
|
2028
2113
|
class FileStreamer
|
@@ -2044,6 +2129,16 @@ class API < Grape::API
|
|
2044
2129
|
end
|
2045
2130
|
```
|
2046
2131
|
|
2132
|
+
If you want a file-like object to be streamed using Rack::Chunked, use `stream`.
|
2133
|
+
|
2134
|
+
```ruby
|
2135
|
+
class API < Grape::API
|
2136
|
+
get '/' do
|
2137
|
+
stream FileStreamer.new('file.bin')
|
2138
|
+
end
|
2139
|
+
end
|
2140
|
+
```
|
2141
|
+
|
2047
2142
|
## Authentication
|
2048
2143
|
|
2049
2144
|
### Basic and Digest Auth
|
@@ -2534,6 +2629,34 @@ See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-
|
|
2534
2629
|
|
2535
2630
|
## Performance Monitoring
|
2536
2631
|
|
2632
|
+
### Active Support Instrumentation
|
2633
|
+
|
2634
|
+
Grape has built-in support for [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) which provides simple hook points to instrument key parts of your application.
|
2635
|
+
|
2636
|
+
The following are currently supported:
|
2637
|
+
|
2638
|
+
#### endpoint_run.grape
|
2639
|
+
|
2640
|
+
The main execution of an endpoint, includes filters and rendering.
|
2641
|
+
|
2642
|
+
* *endpoint* - The endpoint instance
|
2643
|
+
|
2644
|
+
#### endpoint_render.grape
|
2645
|
+
|
2646
|
+
The execution of the main content block of the endpoint.
|
2647
|
+
|
2648
|
+
* *endpoint* - The endpoint instance
|
2649
|
+
|
2650
|
+
#### endpoint_run_filters.grape
|
2651
|
+
|
2652
|
+
* *endpoint* - The endpoint instance
|
2653
|
+
* *filters* - The filters being executed
|
2654
|
+
* *type* - The type of filters (before, before_validation, after_validation, after)
|
2655
|
+
|
2656
|
+
See the [ActiveSupport::Notifications documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html] for information on how to subscribe to these events.
|
2657
|
+
|
2658
|
+
### Monitoring Products
|
2659
|
+
|
2537
2660
|
Grape integrates with NewRelic via the
|
2538
2661
|
[newrelic-grape](https://github.com/flyerhzm/newrelic-grape) gem, and
|
2539
2662
|
with Librato Metrics with the [grape-librato](https://github.com/seanmoon/grape-librato) gem.
|
@@ -2550,7 +2673,7 @@ See [CONTRIBUTING](CONTRIBUTING.md).
|
|
2550
2673
|
You can start hacking on Grape on
|
2551
2674
|
[Nitrous.IO](https://www.nitrous.io/?utm_source=github.com&utm_campaign=grape&utm_medium=hackonnitrous) in a matter of seconds:
|
2552
2675
|
|
2553
|
-
[![Hack
|
2676
|
+
[![Hack ruby-grape/grape on Nitrous.IO](https://d3o0mnbgv6k92a.cloudfront.net/assets/hack-l-v1-3cc067e71372f6045e1949af9d96095b.png)](https://www.nitrous.io/hack_button?source=embed&runtime=rails&repo=intridea%2Fgrape&file_to_open=README.md)
|
2554
2677
|
|
2555
2678
|
## License
|
2556
2679
|
|
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
@@ -44,7 +44,7 @@ begin
|
|
44
44
|
Dir.mkdir(dir)
|
45
45
|
Dir.chdir(dir) do
|
46
46
|
system('git init')
|
47
|
-
system('git remote add origin git@github.com:
|
47
|
+
system('git remote add origin git@github.com:ruby-grape/grape.git')
|
48
48
|
system('git pull')
|
49
49
|
system('git checkout gh-pages')
|
50
50
|
end
|
data/UPGRADING.md
CHANGED
@@ -29,13 +29,13 @@ class CacheBusterMiddleware < Grape::Middleware::Base
|
|
29
29
|
end
|
30
30
|
```
|
31
31
|
|
32
|
-
See [#1029](https://github.com/
|
32
|
+
See [#1029](https://github.com/ruby-grape/grape/pull/1029) for more information.
|
33
33
|
|
34
34
|
#### Changes in present
|
35
35
|
|
36
36
|
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
37
|
|
38
|
-
See [grape-with-roar#5](https://github.com/dblock/grape-with-roar/issues/5) and [#1023](https://github.com/
|
38
|
+
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
39
|
|
40
40
|
#### Changes to regexp validator
|
41
41
|
|
@@ -47,7 +47,7 @@ params do
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
-
See [#957](https://github.com/
|
50
|
+
See [#957](https://github.com/ruby-grape/grape/pull/957) for more information.
|
51
51
|
|
52
52
|
#### Replace error_response with error! in rescue_from blocks
|
53
53
|
|
@@ -88,11 +88,11 @@ Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finis
|
|
88
88
|
error!(e)
|
89
89
|
```
|
90
90
|
|
91
|
-
See [#889](https://github.com/
|
91
|
+
See [#889](https://github.com/ruby-grape/grape/issues/889) for more information.
|
92
92
|
|
93
93
|
#### Changes to routes when using `format`
|
94
94
|
|
95
|
-
Version 0.10.0 has introduced a change via [#809](https://github.com/
|
95
|
+
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
96
|
|
97
97
|
```ruby
|
98
98
|
class API < Grape::API
|
@@ -108,7 +108,7 @@ Will respond with JSON to `/hello` **and** `/hello.json`.
|
|
108
108
|
|
109
109
|
Will respond with 404 to `/hello.xml`, `/hello.txt` etc.
|
110
110
|
|
111
|
-
See the [#1001](https://github.com/
|
111
|
+
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
112
|
|
113
113
|
### Upgrading to >= 0.11.0
|
114
114
|
|
@@ -120,20 +120,20 @@ Grape now supports, but doesn't require Rack 1.6.0. If you encounter an issue wi
|
|
120
120
|
gem 'rack', '~> 1.6.0'
|
121
121
|
```
|
122
122
|
|
123
|
-
See [#559](https://github.com/
|
123
|
+
See [#559](https://github.com/ruby-grape/grape/issues/559) for more information.
|
124
124
|
|
125
125
|
#### Removed route_info
|
126
126
|
|
127
127
|
Key route_info is excluded from params.
|
128
128
|
|
129
|
-
See [#879](https://github.com/
|
129
|
+
See [#879](https://github.com/ruby-grape/grape/pull/879) for more information.
|
130
130
|
|
131
131
|
|
132
132
|
#### Fix callbacks within a version block
|
133
133
|
|
134
134
|
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
135
|
|
136
|
-
See [#901](https://github.com/
|
136
|
+
See [#901](https://github.com/ruby-grape/grape/pull/901) for more information.
|
137
137
|
|
138
138
|
|
139
139
|
#### Make type of group of parameters required
|
@@ -141,7 +141,7 @@ See [#901](https://github.com/intridea/grape/pull/901) for more information.
|
|
141
141
|
Groups of parameters now require their type to be set explicitly as Array or Hash.
|
142
142
|
Not setting the type now results in MissingGroupTypeError, unsupported type will raise UnsupportedTypeError.
|
143
143
|
|
144
|
-
See [#886](https://github.com/
|
144
|
+
See [#886](https://github.com/ruby-grape/grape/pull/886) for more information.
|
145
145
|
|
146
146
|
### Upgrading to >= 0.10.1
|
147
147
|
|
@@ -149,7 +149,7 @@ See [#886](https://github.com/intridea/grape/pull/886) for more information.
|
|
149
149
|
|
150
150
|
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
151
|
|
152
|
-
See [#864](https://github.com/
|
152
|
+
See [#864](https://github.com/ruby-grape/grape/pull/864) for more information.
|
153
153
|
|
154
154
|
### Upgrading to >= 0.10.0
|
155
155
|
|
@@ -284,13 +284,13 @@ get do
|
|
284
284
|
end
|
285
285
|
```
|
286
286
|
|
287
|
-
For more information see [#836](https://github.com/
|
287
|
+
For more information see [#836](https://github.com/ruby-grape/grape/issues/836).
|
288
288
|
|
289
289
|
#### Changes to Custom Validators
|
290
290
|
|
291
291
|
To implement a custom validator, you need to inherit from `Grape::Validations::Base` instead of `Grape::Validations::Validator`.
|
292
292
|
|
293
|
-
For more information see [Custom Validators](https://github.com/
|
293
|
+
For more information see [Custom Validators](https://github.com/ruby-grape/grape#custom-validators) in the documentation.
|
294
294
|
|
295
295
|
#### Changes to Raising Grape::Exceptions::Validation
|
296
296
|
|
@@ -337,7 +337,7 @@ class API < Grape::API
|
|
337
337
|
end
|
338
338
|
```
|
339
339
|
|
340
|
-
See the [the updated API Formats documentation](https://github.com/
|
340
|
+
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
341
|
|
342
342
|
#### Changes to Evaluation of Permitted Parameter Values
|
343
343
|
|
@@ -357,7 +357,7 @@ params do
|
|
357
357
|
end
|
358
358
|
```
|
359
359
|
|
360
|
-
See [#801](https://github.com/
|
360
|
+
See [#801](https://github.com/ruby-grape/grape/issues/801) for more information.
|
361
361
|
|
362
362
|
#### Changes to version
|
363
363
|
|
@@ -389,7 +389,7 @@ end
|
|
389
389
|
|
390
390
|
when making a API call `GET /foo/v2/1`, the API would set instance variable `@output` to `hello1-v2`
|
391
391
|
|
392
|
-
See [#898](https://github.com/
|
392
|
+
See [#898](https://github.com/ruby-grape/grape/issues/898) for more information.
|
393
393
|
|
394
394
|
|
395
395
|
### Upgrading to >= 0.9.0
|
@@ -422,10 +422,10 @@ As replacement can be used
|
|
422
422
|
* `Grape::Middleware::Auth::Digest` => [`Rack::Auth::Digest::MD5`](https://github.com/rack/rack/blob/master/lib/rack/auth/digest/md5.rb)
|
423
423
|
* `Grape::Middleware::Auth::OAuth2` => [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2)
|
424
424
|
|
425
|
-
If this is not possible you can extract the middleware files from [grape v0.7.0](https://github.com/
|
425
|
+
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
426
|
and host these files within your application
|
427
427
|
|
428
|
-
See [#703](https://github.com/
|
428
|
+
See [#703](https://github.com/ruby-grape/Grape/pull/703) for more information.
|
429
429
|
|
430
430
|
### Upgrading to >= 0.7.0
|
431
431
|
|
@@ -462,7 +462,7 @@ rescue_from ParentError, rescue_subclasses: false do |e|
|
|
462
462
|
end
|
463
463
|
```
|
464
464
|
|
465
|
-
See [#544](https://github.com/
|
465
|
+
See [#544](https://github.com/ruby-grape/grape/pull/544) for more information.
|
466
466
|
|
467
467
|
|
468
468
|
#### Changes in the Default HTTP Status Code
|
@@ -485,7 +485,7 @@ You may also use `default_error_status` to change the global default.
|
|
485
485
|
default_error_status 400
|
486
486
|
```
|
487
487
|
|
488
|
-
See [#525](https://github.com/
|
488
|
+
See [#525](https://github.com/ruby-grape/Grape/pull/525) for more information.
|
489
489
|
|
490
490
|
|
491
491
|
#### Changes in Parameter Declaration and Validation
|
@@ -502,7 +502,7 @@ params do
|
|
502
502
|
end
|
503
503
|
```
|
504
504
|
|
505
|
-
This caused the ambiguity and unexpected errors described in [#543](https://github.com/
|
505
|
+
This caused the ambiguity and unexpected errors described in [#543](https://github.com/ruby-grape/Grape/issues/543).
|
506
506
|
|
507
507
|
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
508
|
|
@@ -530,7 +530,7 @@ params do
|
|
530
530
|
end
|
531
531
|
```
|
532
532
|
|
533
|
-
See [#545](https://github.com/
|
533
|
+
See [#545](https://github.com/ruby-grape/Grape/pull/545) for more information.
|
534
534
|
|
535
535
|
|
536
536
|
### Upgrading to 0.6.0
|
@@ -547,4 +547,4 @@ rescue_from Grape::Exceptions::Validations do |e|
|
|
547
547
|
end
|
548
548
|
```
|
549
549
|
|
550
|
-
For more information see [#462](https://github.com/
|
550
|
+
For more information see [#462](https://github.com/ruby-grape/grape/issues/462).
|
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'
|
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
|