grape 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/CONTRIBUTING.md +1 -1
- data/README.md +120 -19
- data/UPGRADING.md +19 -4
- data/lib/grape/api/instance.rb +1 -1
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/callbacks.rb +0 -2
- data/lib/grape/dsl/configuration.rb +0 -2
- data/lib/grape/dsl/desc.rb +0 -15
- data/lib/grape/dsl/helpers.rb +0 -2
- data/lib/grape/dsl/inside_route.rb +33 -29
- data/lib/grape/dsl/middleware.rb +0 -2
- data/lib/grape/dsl/parameters.rb +5 -7
- data/lib/grape/dsl/request_response.rb +0 -2
- data/lib/grape/dsl/routing.rb +4 -2
- data/lib/grape/dsl/settings.rb +0 -2
- data/lib/grape/dsl/validations.rb +0 -15
- data/lib/grape/error_formatter/json.rb +7 -1
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +8 -1
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
- data/lib/grape/exceptions/validation.rb +0 -4
- data/lib/grape/locale/en.yml +9 -8
- data/lib/grape/middleware/auth/dsl.rb +0 -1
- data/lib/grape/middleware/error.rb +2 -2
- data/lib/grape/request.rb +2 -0
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +66 -40
- data/lib/grape/validations/types/array_coercer.rb +2 -2
- data/lib/grape/validations/types/build_coercer.rb +94 -0
- data/lib/grape/validations/types/dry_type_coercer.rb +13 -8
- data/lib/grape/validations/types/json.rb +2 -0
- data/lib/grape/validations/types/primitive_coercer.rb +20 -10
- data/lib/grape/validations/types/set_coercer.rb +3 -2
- data/lib/grape/validations/types.rb +20 -26
- data/lib/grape/validations/validators/base.rb +7 -0
- data/lib/grape/validations.rb +16 -6
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +20 -15
- data/spec/grape/api/custom_validations_spec.rb +41 -2
- data/spec/grape/api/deeply_included_options_spec.rb +0 -2
- data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -2
- data/spec/grape/api/documentation_spec.rb +59 -0
- data/spec/grape/api/inherited_helpers_spec.rb +0 -2
- data/spec/grape/api/instance_spec.rb +0 -1
- data/spec/grape/api/invalid_format_spec.rb +0 -2
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/nested_helpers_spec.rb +0 -2
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/parameters_modification_spec.rb +0 -2
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
- data/spec/grape/api/recognize_path_spec.rb +0 -2
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
- data/spec/grape/api/routes_with_requirements_spec.rb +0 -2
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -2
- data/spec/grape/api/shared_helpers_spec.rb +0 -2
- data/spec/grape/api_remount_spec.rb +0 -1
- data/spec/grape/api_spec.rb +18 -5
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +0 -2
- data/spec/grape/dsl/configuration_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +0 -2
- data/spec/grape/dsl/headers_spec.rb +2 -4
- data/spec/grape/dsl/helpers_spec.rb +0 -2
- data/spec/grape/dsl/inside_route_spec.rb +10 -12
- data/spec/grape/dsl/logger_spec.rb +0 -2
- data/spec/grape/dsl/middleware_spec.rb +0 -2
- data/spec/grape/dsl/parameters_spec.rb +0 -2
- data/spec/grape/dsl/request_response_spec.rb +6 -8
- data/spec/grape/dsl/routing_spec.rb +1 -3
- data/spec/grape/dsl/settings_spec.rb +0 -2
- data/spec/grape/dsl/validations_spec.rb +0 -17
- data/spec/grape/endpoint/declared_spec.rb +2 -4
- data/spec/grape/endpoint_spec.rb +22 -3
- data/spec/grape/entity_spec.rb +0 -1
- data/spec/grape/exceptions/base_spec.rb +16 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
- data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -3
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +0 -1
- data/spec/grape/exceptions/validation_spec.rb +1 -3
- data/spec/grape/extensions/param_builders/hash_spec.rb +0 -2
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -2
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -2
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +0 -2
- data/spec/grape/integration/rack_spec.rb +0 -2
- data/spec/grape/loading_spec.rb +0 -2
- data/spec/grape/middleware/auth/base_spec.rb +0 -1
- data/spec/grape/middleware/auth/dsl_spec.rb +0 -2
- data/spec/grape/middleware/auth/strategies_spec.rb +0 -2
- data/spec/grape/middleware/base_spec.rb +0 -2
- data/spec/grape/middleware/error_spec.rb +6 -1
- data/spec/grape/middleware/exception_spec.rb +0 -2
- data/spec/grape/middleware/formatter_spec.rb +0 -2
- data/spec/grape/middleware/globals_spec.rb +0 -2
- data/spec/grape/middleware/stack_spec.rb +0 -2
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -2
- data/spec/grape/middleware/versioner/header_spec.rb +18 -4
- data/spec/grape/middleware/versioner/param_spec.rb +0 -2
- data/spec/grape/middleware/versioner/path_spec.rb +0 -2
- data/spec/grape/middleware/versioner_spec.rb +0 -2
- data/spec/grape/named_api_spec.rb +0 -2
- data/spec/grape/parser_spec.rb +0 -2
- data/spec/grape/path_spec.rb +0 -2
- data/spec/grape/presenters/presenter_spec.rb +0 -2
- data/spec/grape/request_spec.rb +0 -2
- data/spec/grape/util/inheritable_setting_spec.rb +0 -1
- data/spec/grape/util/inheritable_values_spec.rb +0 -1
- data/spec/grape/util/reverse_stackable_values_spec.rb +0 -1
- data/spec/grape/util/stackable_values_spec.rb +0 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
- data/spec/grape/validations/attributes_doc_spec.rb +153 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/instance_behaivour_spec.rb +0 -2
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/params_scope_spec.rb +315 -86
- data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -2
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
- data/spec/grape/validations/types/primitive_coercer_spec.rb +20 -5
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
- data/spec/grape/validations/types_spec.rb +28 -2
- data/spec/grape/validations/validators/all_or_none_spec.rb +0 -2
- data/spec/grape/validations/validators/allow_blank_spec.rb +0 -2
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -2
- data/spec/grape/validations/validators/coerce_spec.rb +0 -2
- data/spec/grape/validations/validators/default_spec.rb +0 -2
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -2
- data/spec/grape/validations/validators/except_values_spec.rb +0 -2
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -2
- data/spec/grape/validations/validators/presence_spec.rb +0 -2
- data/spec/grape/validations/validators/regexp_spec.rb +0 -2
- data/spec/grape/validations/validators/same_as_spec.rb +0 -2
- data/spec/grape/validations/validators/values_spec.rb +0 -2
- data/spec/grape/validations_spec.rb +50 -22
- data/spec/integration/multi_json/json_spec.rb +0 -2
- data/spec/integration/multi_xml/xml_spec.rb +0 -2
- data/spec/spec_helper.rb +9 -4
- metadata +17 -8
- data/spec/support/eager_load.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c13bf4d5de206b76e7cccbe4ffa454512986457b8f5d055cde0cfac5d4f164a9
|
4
|
+
data.tar.gz: 1177df9af2a24d80e01366f3d705f29e4180898f4cc1ac7e0221e8412e36dcf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32a0d1d9ae7d16b9760f8919814b2aa362ec95a666159a6dc8314946e8a9fd2461d8c074f705ac7afa21939d2a43bec4196a8b7803efdae967b2d01acd1ae77a
|
7
|
+
data.tar.gz: 5ca9d54a6db6bc63107c2bd0b17cb747f293ec72bc3c0d57a7f7514f0c1122774bce82c5411f4fa19f1c7b435d2c3d1d87102e3f83ff5c31aa8a0dc531817e4d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
### 1.7.0 (2022/12/20)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#2233](https://github.com/ruby-grape/grape/pull/2233): Added `do_not_document!` for disabling documentation to internal APIs - [@dnesteryuk](https://github.com/dnesteryuk).
|
6
|
+
* [#2235](https://github.com/ruby-grape/grape/pull/2235): Add support for Ruby 3.1 - [@petergoldstein](https://github.com/petergoldstein).
|
7
|
+
* [#2248](https://github.com/ruby-grape/grape/pull/2248): Upgraded to rspec 3.11.0 - [@dblock](https://github.com/dblock).
|
8
|
+
* [#2249](https://github.com/ruby-grape/grape/pull/2249): Split CI matrix, extract edge - [@dblock](https://github.com/dblock).
|
9
|
+
* [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock).
|
10
|
+
* [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed).
|
11
|
+
* [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock).
|
12
|
+
* [#2272](https://github.com/ruby-grape/grape/pull/2272): Added error on param init when provided type does not have `[]` coercion method, previously validation silently failed for any value - [@vasfed](https://github.com/Vasfed).
|
13
|
+
* [#2274](https://github.com/ruby-grape/grape/pull/2274): Error middleware support using rack util's symbols as status - [@dhruvCW](https://github.com/dhruvCW).
|
14
|
+
* [#2276](https://github.com/ruby-grape/grape/pull/2276): Fix exception super - [@ericproulx](https://github.com/ericproulx).
|
15
|
+
* [#2285](https://github.com/ruby-grape/grape/pull/2285), [#2287](https://github.com/ruby-grape/grape/pull/2287): Added :evaluate_given to declared(params) - [@zysend](https://github.com/zysend).
|
16
|
+
|
17
|
+
#### Fixes
|
18
|
+
|
19
|
+
* [#2263](https://github.com/ruby-grape/grape/pull/2263): Explicitly require `bigdecimal` and `date` - [@dblock](https://github.com/dblock).
|
20
|
+
* [#2222](https://github.com/ruby-grape/grape/pull/2222): Autoload types and validators - [@ericproulx](https://github.com/ericproulx).
|
21
|
+
* [#2232](https://github.com/ruby-grape/grape/pull/2232): Fix kwargs support in shared params definition - [@dm1try](https://github.com/dm1try).
|
22
|
+
* [#2229](https://github.com/ruby-grape/grape/pull/2229): Do not collect params in route settings - [@dnesteryuk](https://github.com/dnesteryuk).
|
23
|
+
* [#2234](https://github.com/ruby-grape/grape/pull/2234): Remove non-UTF8 characters from format before generating JSON error - [@bschmeck](https://github.com/bschmeck).
|
24
|
+
* [#2227](https://github.com/ruby-grape/grape/pull/2222): Rename `MissingGroupType` and `UnsupportedGroupType` exceptions - [@ericproulx](https://github.com/ericproulx).
|
25
|
+
* [#2244](https://github.com/ruby-grape/grape/pull/2244): Fix a breaking change in `Grape::Validations` provided in 1.6.1 - [@dm1try](https://github.com/dm1try).
|
26
|
+
* [#2250](https://github.com/ruby-grape/grape/pull/2250): Add deprecation warning for `UnsupportedGroupTypeError` and `MissingGroupTypeError` - [@ericproulx](https://github.com/ericproulx).
|
27
|
+
* [#2256](https://github.com/ruby-grape/grape/pull/2256): Raise `Grape::Exceptions::MultipartPartLimitError` from Rack when too many files are uploaded - [@bschmeck](https://github.com/bschmeck).
|
28
|
+
* [#2266](https://github.com/ruby-grape/grape/pull/2266): Fix code coverage - [@duffn](https://github.com/duffn).
|
29
|
+
* [#2284](https://github.com/ruby-grape/grape/pull/2284): Fix an unexpected backtick - [@zysend](https://github.com/zysend).
|
30
|
+
|
31
|
+
### 1.6.2 (2021/12/30)
|
32
|
+
|
33
|
+
#### Fixes
|
34
|
+
|
35
|
+
* [#2219](https://github.com/ruby-grape/grape/pull/2219): Revert the changes for autoloading provided in 1.6.1 - [@dm1try](https://github.com/dm1try).
|
36
|
+
|
1
37
|
### 1.6.1 (2021/12/28)
|
2
38
|
|
3
39
|
#### Features
|
data/CONTRIBUTING.md
CHANGED
@@ -119,7 +119,7 @@ Go back to your pull request after a few minutes and see whether it passed muste
|
|
119
119
|
|
120
120
|
#### Be Patient
|
121
121
|
|
122
|
-
It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang
|
122
|
+
It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang in there!
|
123
123
|
|
124
124
|
#### Thank You
|
125
125
|
|
data/README.md
CHANGED
@@ -40,6 +40,7 @@
|
|
40
40
|
- [Declared](#declared)
|
41
41
|
- [Include Parent Namespaces](#include-parent-namespaces)
|
42
42
|
- [Include Missing](#include-missing)
|
43
|
+
- [Evaluate Given](#evaluate-given)
|
43
44
|
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
|
44
45
|
- [Supported Parameter Types](#supported-parameter-types)
|
45
46
|
- [Integer/Fixnum and Coercions](#integerfixnum-and-coercions)
|
@@ -158,7 +159,7 @@ content negotiation, versioning and much more.
|
|
158
159
|
|
159
160
|
## Stable Release
|
160
161
|
|
161
|
-
You're reading the documentation for the stable release of Grape,
|
162
|
+
You're reading the documentation for the stable release of Grape, 1.7.0.
|
162
163
|
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
163
164
|
|
164
165
|
## Project Resources
|
@@ -174,21 +175,13 @@ Available as part of the Tidelift Subscription.
|
|
174
175
|
|
175
176
|
The maintainers of Grape are working with Tidelift to deliver commercial support and maintenance. Save time, reduce risk, and improve code health, while paying the maintainers of Grape. Click [here](https://tidelift.com/subscription/request-a-demo?utm_source=rubygems-grape&utm_medium=referral&utm_campaign=enterprise) for more details.
|
176
177
|
|
177
|
-
In 2020, we plan to use the money towards gathering Grape contributors for dinner in New York City.
|
178
|
-
|
179
178
|
## Installation
|
180
179
|
|
181
180
|
Ruby 2.4 or newer is required.
|
182
181
|
|
183
|
-
Grape is available as a gem, to install it
|
184
|
-
|
185
|
-
gem install grape
|
186
|
-
|
187
|
-
If you're using Bundler, add the gem to Gemfile.
|
182
|
+
Grape is available as a gem, to install it run:
|
188
183
|
|
189
|
-
|
190
|
-
|
191
|
-
Run `bundle install`.
|
184
|
+
bundle add grape
|
192
185
|
|
193
186
|
## Basic Usage
|
194
187
|
|
@@ -1085,6 +1078,102 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d
|
|
1085
1078
|
}
|
1086
1079
|
````
|
1087
1080
|
|
1081
|
+
### Evaluate Given
|
1082
|
+
|
1083
|
+
By default `declared(params)` will not evaluate `given` and return all parameters. Use `evaluate_given` to evaluate all `given` blocks and return only parameters that satisfy `given` conditions. Consider the following API:
|
1084
|
+
|
1085
|
+
````ruby
|
1086
|
+
format :json
|
1087
|
+
|
1088
|
+
params do
|
1089
|
+
optional :child_id, type: Integer
|
1090
|
+
given :child_id do
|
1091
|
+
requires :father_id, type: Integer
|
1092
|
+
end
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
post 'child' do
|
1096
|
+
{ 'declared_params' => declared(params, evaluate_given: true) }
|
1097
|
+
end
|
1098
|
+
````
|
1099
|
+
|
1100
|
+
**Request**
|
1101
|
+
|
1102
|
+
````bash
|
1103
|
+
curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"father_id": 1}'
|
1104
|
+
````
|
1105
|
+
|
1106
|
+
**Response with evaluate_given:false**
|
1107
|
+
|
1108
|
+
````json
|
1109
|
+
{
|
1110
|
+
"declared_params": {
|
1111
|
+
"child_id": null,
|
1112
|
+
"father_id": 1
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
````
|
1116
|
+
|
1117
|
+
**Response with evaluate_given:true**
|
1118
|
+
|
1119
|
+
````json
|
1120
|
+
{
|
1121
|
+
"declared_params": {
|
1122
|
+
"child_id": null
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
````
|
1126
|
+
|
1127
|
+
It also works on nested hashes:
|
1128
|
+
|
1129
|
+
````ruby
|
1130
|
+
format :json
|
1131
|
+
|
1132
|
+
params do
|
1133
|
+
requires :child, type: Hash do
|
1134
|
+
optional :child_id, type: Integer
|
1135
|
+
given :child_id do
|
1136
|
+
requires :father_id, type: Integer
|
1137
|
+
end
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
post 'child' do
|
1142
|
+
{ 'declared_params' => declared(params, evaluate_given: true) }
|
1143
|
+
end
|
1144
|
+
````
|
1145
|
+
|
1146
|
+
**Request**
|
1147
|
+
|
1148
|
+
````bash
|
1149
|
+
curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"child": {"father_id": 1}}'
|
1150
|
+
````
|
1151
|
+
|
1152
|
+
**Response with evaluate_given:false**
|
1153
|
+
|
1154
|
+
````json
|
1155
|
+
{
|
1156
|
+
"declared_params": {
|
1157
|
+
"child": {
|
1158
|
+
"child_id": null,
|
1159
|
+
"father_id": 1
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
}
|
1163
|
+
````
|
1164
|
+
|
1165
|
+
**Response with evaluate_given:true**
|
1166
|
+
|
1167
|
+
````json
|
1168
|
+
{
|
1169
|
+
"declared_params": {
|
1170
|
+
"child": {
|
1171
|
+
"child_id": null
|
1172
|
+
}
|
1173
|
+
}
|
1174
|
+
}
|
1175
|
+
````
|
1176
|
+
|
1088
1177
|
## Parameter Validation and Coercion
|
1089
1178
|
|
1090
1179
|
You can define validations and coercion options for your parameters using a `params` block.
|
@@ -1453,7 +1542,7 @@ resource :users do
|
|
1453
1542
|
end
|
1454
1543
|
```
|
1455
1544
|
|
1456
|
-
The value passed to `as` will be the key when calling `
|
1545
|
+
The value passed to `as` will be the key when calling `declared(params)`.
|
1457
1546
|
|
1458
1547
|
### Built-in Validators
|
1459
1548
|
|
@@ -1742,10 +1831,10 @@ end
|
|
1742
1831
|
### Custom Validators
|
1743
1832
|
|
1744
1833
|
```ruby
|
1745
|
-
class AlphaNumeric < Grape::Validations::Base
|
1834
|
+
class AlphaNumeric < Grape::Validations::Validators::Base
|
1746
1835
|
def validate_param!(attr_name, params)
|
1747
1836
|
unless params[attr_name] =~ /\A[[:alnum:]]+\z/
|
1748
|
-
|
1837
|
+
raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: 'must consist of alpha-numeric characters'
|
1749
1838
|
end
|
1750
1839
|
end
|
1751
1840
|
end
|
@@ -1760,10 +1849,10 @@ end
|
|
1760
1849
|
You can also create custom classes that take parameters.
|
1761
1850
|
|
1762
1851
|
```ruby
|
1763
|
-
class Length < Grape::Validations::Base
|
1852
|
+
class Length < Grape::Validations::Validators::Base
|
1764
1853
|
def validate_param!(attr_name, params)
|
1765
1854
|
unless params[attr_name].length <= @option
|
1766
|
-
|
1855
|
+
raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
|
1767
1856
|
end
|
1768
1857
|
end
|
1769
1858
|
end
|
@@ -1778,7 +1867,7 @@ end
|
|
1778
1867
|
You can also create custom validation that use request to validate the attribute. For example if you want to have parameters that are available to only admins, you can do the following.
|
1779
1868
|
|
1780
1869
|
```ruby
|
1781
|
-
class Admin < Grape::Validations::Base
|
1870
|
+
class Admin < Grape::Validations::Validators::Base
|
1782
1871
|
def validate(request)
|
1783
1872
|
# return if the param we are checking was not in request
|
1784
1873
|
# @attrs is a list containing the attribute we are currently validating
|
@@ -1789,7 +1878,7 @@ class Admin < Grape::Validations::Base
|
|
1789
1878
|
return unless @option
|
1790
1879
|
# check if user is admin or not
|
1791
1880
|
# as an example get a token from request and check if it's admin or not
|
1792
|
-
|
1881
|
+
raise Grape::Exceptions::Validation.new params: @attrs, message: 'Can not set admin-only field.' unless request.headers['X-Access-Token'] == 'admin'
|
1793
1882
|
end
|
1794
1883
|
end
|
1795
1884
|
```
|
@@ -2248,6 +2337,18 @@ params do
|
|
2248
2337
|
end
|
2249
2338
|
```
|
2250
2339
|
|
2340
|
+
If documentation isn't needed (for instance, it is an internal API), documentation can be disabled.
|
2341
|
+
|
2342
|
+
```ruby
|
2343
|
+
class API < Grape::API
|
2344
|
+
do_not_document!
|
2345
|
+
|
2346
|
+
# endpoints...
|
2347
|
+
end
|
2348
|
+
```
|
2349
|
+
|
2350
|
+
In this case, Grape won't create objects related to documentation which are retained in RAM forever.
|
2351
|
+
|
2251
2352
|
## Cookies
|
2252
2353
|
|
2253
2354
|
You can set, get and delete your cookies very simply using `cookies` method.
|
@@ -3701,7 +3802,7 @@ Use `rack-test` and define your API as `app`.
|
|
3701
3802
|
You can test a Grape API with RSpec by making HTTP requests and examining the response.
|
3702
3803
|
|
3703
3804
|
```ruby
|
3704
|
-
|
3805
|
+
|
3705
3806
|
|
3706
3807
|
describe Twitter::API do
|
3707
3808
|
include Rack::Test::Methods
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
Upgrading Grape
|
2
2
|
===============
|
3
3
|
|
4
|
+
### Upgrading to >= 1.7.0
|
5
|
+
|
6
|
+
#### Exceptions renaming
|
7
|
+
|
8
|
+
The following exceptions has been renamed for consistency through exceptions naming :
|
9
|
+
|
10
|
+
* `MissingGroupTypeError` => `MissingGroupType`
|
11
|
+
* `UnsupportedGroupTypeError` => `UnsupportedGroupType`
|
12
|
+
|
13
|
+
See [#2227](https://github.com/ruby-grape/grape/pull/2227) for more information.
|
14
|
+
|
15
|
+
#### Handling Multipart Limit Errors
|
16
|
+
|
17
|
+
Rack supports a configurable limit on the number of files created from multipart parameters (`Rack::Utils.multipart_part_limit`) and raises an error if params are received that create too many files. If you were handling the Rack error directly, Grape now wraps that error in `Grape::Execeptions::TooManyMultipartFiles`. Additionally, Grape will return a 413 status code if the exception goes unhandled.
|
18
|
+
|
4
19
|
### Upgrading to >= 1.6.0
|
5
20
|
|
6
21
|
#### Parameter renaming with :as
|
@@ -27,7 +42,7 @@ declared(params, include_missing: false)
|
|
27
42
|
# actual => { b: '5' } (uncasted, unvalidated, <= 1.5.3)
|
28
43
|
```
|
29
44
|
|
30
|
-
Another implication of this change is the dependent parameter resolution. Prior to 1.6.0 the following code produced
|
45
|
+
Another implication of this change is the dependent parameter resolution. Prior to 1.6.0 the following code produced a `Grape::Exceptions::UnknownParameter` because `:a` was replaced by `:b`:
|
31
46
|
|
32
47
|
```ruby
|
33
48
|
params do
|
@@ -47,7 +62,7 @@ See [#2189](https://github.com/ruby-grape/grape/pull/2189) for more information.
|
|
47
62
|
#### Nil value and coercion
|
48
63
|
|
49
64
|
Prior to 1.2.5 version passing a `nil` value for a parameter with a custom coercer would invoke the coercer, and not passing a parameter would not invoke it.
|
50
|
-
This behavior was not tested or documented. Version 1.3.0 quietly changed this behavior, in
|
65
|
+
This behavior was not tested or documented. Version 1.3.0 quietly changed this behavior, in that `nil` values skipped the coercion. Version 1.5.3 fixes and documents this as follows:
|
51
66
|
|
52
67
|
```ruby
|
53
68
|
class Api < Grape::API
|
@@ -197,13 +212,13 @@ end
|
|
197
212
|
|
198
213
|
#### Nil values for structures
|
199
214
|
|
200
|
-
Nil values always been a special case when dealing with types especially with the following structures:
|
215
|
+
Nil values have always been a special case when dealing with types, especially with the following structures:
|
201
216
|
|
202
217
|
- Array
|
203
218
|
- Hash
|
204
219
|
- Set
|
205
220
|
|
206
|
-
The behavior for these structures has
|
221
|
+
The behavior for these structures has changed throughout the latest releases. For example:
|
207
222
|
|
208
223
|
```ruby
|
209
224
|
class Api < Grape::API
|
data/lib/grape/api/instance.rb
CHANGED
@@ -101,7 +101,7 @@ module Grape
|
|
101
101
|
# block passed in. Allows for simple 'before' setups
|
102
102
|
# of settings stack pushes.
|
103
103
|
def nest(*blocks, &block)
|
104
|
-
blocks.
|
104
|
+
blocks.compact!
|
105
105
|
if blocks.any?
|
106
106
|
evaluate_as_instance_with_configuration(block) if block
|
107
107
|
blocks.each { |b| evaluate_as_instance_with_configuration(b) }
|
data/lib/grape/dsl/api.rb
CHANGED
data/lib/grape/dsl/callbacks.rb
CHANGED
data/lib/grape/dsl/desc.rb
CHANGED
@@ -78,21 +78,6 @@ module Grape
|
|
78
78
|
route_setting :description, options
|
79
79
|
end
|
80
80
|
|
81
|
-
def description_field(field, value = nil)
|
82
|
-
description = route_setting(:description)
|
83
|
-
if value
|
84
|
-
description ||= route_setting(:description, {})
|
85
|
-
description[field] = value
|
86
|
-
elsif description
|
87
|
-
description[field]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def unset_description_field(field)
|
92
|
-
description = route_setting(:description)
|
93
|
-
description&.delete(field)
|
94
|
-
end
|
95
|
-
|
96
81
|
# Returns an object which configures itself via an instance-context DSL.
|
97
82
|
def desc_container(endpoint_configuration)
|
98
83
|
Module.new do
|
data/lib/grape/dsl/helpers.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/concern'
|
4
3
|
require 'grape/dsl/headers'
|
5
4
|
|
6
5
|
module Grape
|
@@ -29,7 +28,7 @@ module Grape
|
|
29
28
|
# has completed
|
30
29
|
module PostBeforeFilter
|
31
30
|
def declared(passed_params, options = {}, declared_params = nil, params_nested_path = [])
|
32
|
-
options = options.reverse_merge(include_missing: true, include_parent_namespaces: true)
|
31
|
+
options = options.reverse_merge(include_missing: true, include_parent_namespaces: true, evaluate_given: false)
|
33
32
|
declared_params ||= optioned_declared_params(**options)
|
34
33
|
|
35
34
|
if passed_params.is_a?(Array)
|
@@ -48,41 +47,46 @@ module Grape
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def declared_hash(passed_params, options, declared_params, params_nested_path)
|
51
|
-
|
50
|
+
declared_params.each_with_object(passed_params.class.new) do |declared_param_attr, memo|
|
51
|
+
next if options[:evaluate_given] && !declared_param_attr.scope.attr_meets_dependency?(passed_params)
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
params_nested_path_dup = params_nested_path.dup
|
57
|
-
params_nested_path_dup << declared_parent_param.to_s
|
58
|
-
next unless options[:include_missing] || passed_params.key?(declared_parent_param)
|
53
|
+
declared_hash_attr(passed_params, options, declared_param_attr.key, params_nested_path, memo)
|
54
|
+
end
|
55
|
+
end
|
59
56
|
|
60
|
-
|
61
|
-
|
57
|
+
def declared_hash_attr(passed_params, options, declared_param, params_nested_path, memo)
|
58
|
+
renamed_params = route_setting(:renamed_params) || {}
|
59
|
+
if declared_param.is_a?(Hash)
|
60
|
+
declared_param.each_pair do |declared_parent_param, declared_children_params|
|
61
|
+
params_nested_path_dup = params_nested_path.dup
|
62
|
+
params_nested_path_dup << declared_parent_param.to_s
|
63
|
+
next unless options[:include_missing] || passed_params.key?(declared_parent_param)
|
64
|
+
|
65
|
+
rename_path = params_nested_path + [declared_parent_param.to_s]
|
66
|
+
renamed_param_name = renamed_params[rename_path]
|
62
67
|
|
63
|
-
|
64
|
-
|
68
|
+
memo_key = optioned_param_key(renamed_param_name || declared_parent_param, options)
|
69
|
+
passed_children_params = passed_params[declared_parent_param] || passed_params.class.new
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
end
|
71
|
+
memo[memo_key] = handle_passed_param(params_nested_path_dup, passed_children_params.any?) do
|
72
|
+
declared(passed_children_params, options, declared_children_params, params_nested_path_dup)
|
69
73
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
+
end
|
75
|
+
else
|
76
|
+
# If it is not a Hash then it does not have children.
|
77
|
+
# Find its value or set it to nil.
|
78
|
+
return unless options[:include_missing] || passed_params.key?(declared_param)
|
74
79
|
|
75
|
-
|
76
|
-
|
80
|
+
rename_path = params_nested_path + [declared_param.to_s]
|
81
|
+
renamed_param_name = renamed_params[rename_path]
|
77
82
|
|
78
|
-
|
79
|
-
|
83
|
+
memo_key = optioned_param_key(renamed_param_name || declared_param, options)
|
84
|
+
passed_param = passed_params[declared_param]
|
80
85
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
+
params_nested_path_dup = params_nested_path.dup
|
87
|
+
params_nested_path_dup << declared_param.to_s
|
88
|
+
memo[memo_key] = passed_param || handle_passed_param(params_nested_path_dup) do
|
89
|
+
passed_param
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|
data/lib/grape/dsl/middleware.rb
CHANGED
data/lib/grape/dsl/parameters.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/concern'
|
4
|
-
|
5
3
|
module Grape
|
6
4
|
module DSL
|
7
5
|
# Defines DSL methods, meant to be applied to a ParamsScope, which define
|
@@ -64,7 +62,7 @@ module Grape
|
|
64
62
|
params_block = named_params.fetch(name) do
|
65
63
|
raise "Params :#{name} not found!"
|
66
64
|
end
|
67
|
-
instance_exec(options, ¶ms_block)
|
65
|
+
instance_exec(**options, ¶ms_block)
|
68
66
|
end
|
69
67
|
end
|
70
68
|
alias use_scope use
|
@@ -150,8 +148,8 @@ module Grape
|
|
150
148
|
|
151
149
|
# check type for optional parameter group
|
152
150
|
if attrs && block
|
153
|
-
raise Grape::Exceptions::
|
154
|
-
raise Grape::Exceptions::
|
151
|
+
raise Grape::Exceptions::MissingGroupType if type.nil?
|
152
|
+
raise Grape::Exceptions::UnsupportedGroupType unless Grape::Validations::Types.group?(type)
|
155
153
|
end
|
156
154
|
|
157
155
|
if opts[:using]
|
@@ -219,8 +217,8 @@ module Grape
|
|
219
217
|
else
|
220
218
|
# @declared_params also includes hashes of options and such, but those
|
221
219
|
# won't be flattened out.
|
222
|
-
@declared_params.flatten.any? do |
|
223
|
-
first_hash_key_or_param(
|
220
|
+
@declared_params.flatten.any? do |declared_param_attr|
|
221
|
+
first_hash_key_or_param(declared_param_attr.key) == param
|
224
222
|
end
|
225
223
|
end
|
226
224
|
end
|
data/lib/grape/dsl/routing.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/concern'
|
4
|
-
|
5
3
|
module Grape
|
6
4
|
module DSL
|
7
5
|
module Routing
|
@@ -79,6 +77,10 @@ module Grape
|
|
79
77
|
namespace_inheritable(:do_not_route_options, true)
|
80
78
|
end
|
81
79
|
|
80
|
+
def do_not_document!
|
81
|
+
namespace_inheritable(:do_not_document, true)
|
82
|
+
end
|
83
|
+
|
82
84
|
def mount(mounts, *opts)
|
83
85
|
mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair)
|
84
86
|
mounts.each_pair do |app, path|
|
data/lib/grape/dsl/settings.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/concern'
|
4
|
-
|
5
3
|
module Grape
|
6
4
|
module DSL
|
7
5
|
module Validations
|
@@ -32,7 +30,6 @@ module Grape
|
|
32
30
|
unset_namespace_stackable :declared_params
|
33
31
|
unset_namespace_stackable :validations
|
34
32
|
unset_namespace_stackable :params
|
35
|
-
unset_description_field :params
|
36
33
|
end
|
37
34
|
|
38
35
|
# Opens a root-level ParamsScope, defining parameter coercions and
|
@@ -41,18 +38,6 @@ module Grape
|
|
41
38
|
def params(&block)
|
42
39
|
Grape::Validations::ParamsScope.new(api: self, type: Hash, &block)
|
43
40
|
end
|
44
|
-
|
45
|
-
def document_attribute(names, opts)
|
46
|
-
setting = description_field(:params)
|
47
|
-
setting ||= description_field(:params, {})
|
48
|
-
Array(names).each do |name|
|
49
|
-
full_name = name[:full_name].to_s
|
50
|
-
setting[full_name] ||= {}
|
51
|
-
setting[full_name].merge!(opts)
|
52
|
-
|
53
|
-
namespace_stackable(:params, full_name => opts)
|
54
|
-
end
|
55
|
-
end
|
56
41
|
end
|
57
42
|
end
|
58
43
|
end
|
@@ -21,9 +21,15 @@ module Grape
|
|
21
21
|
if message.is_a?(Exceptions::ValidationErrors) || message.is_a?(Hash)
|
22
22
|
message
|
23
23
|
else
|
24
|
-
{ error: message }
|
24
|
+
{ error: ensure_utf8(message) }
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
def ensure_utf8(message)
|
29
|
+
return message unless message.respond_to? :encode
|
30
|
+
|
31
|
+
message.encode('UTF-8', invalid: :replace, undef: :replace)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -7,12 +7,12 @@ module Grape
|
|
7
7
|
BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'
|
8
8
|
FALLBACK_LOCALE = :en
|
9
9
|
|
10
|
-
attr_reader :status, :
|
10
|
+
attr_reader :status, :headers
|
11
11
|
|
12
12
|
def initialize(status: nil, message: nil, headers: nil, **_options)
|
13
13
|
@status = status
|
14
|
-
@message = message
|
15
14
|
@headers = headers
|
15
|
+
super(message)
|
16
16
|
end
|
17
17
|
|
18
18
|
def [](index)
|