grape 1.6.2 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -1
- data/CONTRIBUTING.md +30 -0
- data/README.md +146 -23
- data/UPGRADING.md +15 -0
- data/grape.gemspec +2 -2
- data/lib/grape/api/instance.rb +1 -1
- data/lib/grape/dry_types.rb +12 -0
- 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 +2 -16
- data/lib/grape/dsl/helpers.rb +0 -2
- data/lib/grape/dsl/inside_route.rb +34 -30
- data/lib/grape/dsl/middleware.rb +0 -2
- data/lib/grape/dsl/parameters.rb +10 -7
- data/lib/grape/dsl/request_response.rb +1 -3
- 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/endpoint.rb +2 -2
- data/lib/grape/error_formatter/json.rb +7 -1
- data/lib/grape/exceptions/base.rb +3 -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/middleware/stack.rb +1 -1
- data/lib/grape/request.rb +3 -1
- data/lib/grape/router/attribute_translator.rb +1 -1
- data/lib/grape/types/invalid_value.rb +8 -0
- data/lib/grape/util/cache.rb +1 -1
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +67 -41
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +3 -7
- data/lib/grape/validations/types/invalid_value.rb +0 -7
- data/lib/grape/validations/types/primitive_coercer.rb +14 -6
- data/lib/grape/validations/types/set_coercer.rb +0 -2
- data/lib/grape/validations/types.rb +98 -30
- data/lib/grape/validations/validators/{all_or_none.rb → all_or_none_of_validator.rb} +0 -2
- data/lib/grape/validations/validators/{at_least_one_of.rb → at_least_one_of_validator.rb} +0 -2
- data/lib/grape/validations/validators/base.rb +7 -0
- data/lib/grape/validations/validators/{exactly_one_of.rb → exactly_one_of_validator.rb} +0 -2
- data/lib/grape/validations/validators/{mutual_exclusion.rb → mutual_exclusion_validator.rb} +0 -2
- data/lib/grape/validations.rb +16 -12
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +74 -28
- 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 +23 -25
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +2 -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 +29 -9
- 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 +3 -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 +6 -7
- 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 +7 -7
- 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 +6 -8
- 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/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 +19 -2
- data/spec/grape/validations_spec.rb +78 -27
- 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 +134 -122
- data/spec/grape/dsl/configuration_spec.rb +0 -16
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
- data/spec/support/eager_load.rb +0 -19
- /data/lib/grape/validations/validators/{allow_blank.rb → allow_blank_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{as.rb → as_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{coerce.rb → coerce_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{default.rb → default_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{except_values.rb → except_values_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{presence.rb → presence_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{regexp.rb → regexp_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{same_as.rb → same_as_validator.rb} +0 -0
- /data/lib/grape/validations/validators/{values.rb → values_validator.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40277732454d8810e4e96f638da9e6bd4ab818e39ac9c30788791cb4bd429871
|
4
|
+
data.tar.gz: b075dd96ba3dda6fcd05e6b1c126255b5e206b2d6bb9bf9b52f9cd6ec25a6efc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61d1ef36c90927e08119b6abf57b87fc5317b7b4ac73587d14bc23c9b671e0e76930b89b22d15ec806861f2c60c582647a4f95bc6a1100dca07066be1853d4e6
|
7
|
+
data.tar.gz: 42a4595d466b2092759dee55ad467a6733e29912b0faaf3abe203c18ab1c84b53b6a1d45868102ac16e6b431254664a6762b3ec0b8e52217c777f99adcf965cc
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,60 @@
|
|
1
|
-
### 1.
|
1
|
+
### 1.7.1 (2023/05/14)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#2288](https://github.com/ruby-grape/grape/pull/2288): Droped support for Ruby 2.5 - [@ericproulx](https://github.com/ericproulx).
|
6
|
+
* [#2288](https://github.com/ruby-grape/grape/pull/2288): Updated rubocop to 1.41.0 - [@ericproulx](https://github.com/ericproulx).
|
7
|
+
* [#2296](https://github.com/ruby-grape/grape/pull/2296): Fix cops and enables some - [@ericproulx](https://github.com/ericproulx).
|
8
|
+
* [#2302](https://github.com/ruby-grape/grape/pull/2302): Rack < 3 and update rack-test - [@ericproulx](https://github.com/ericproulx).
|
9
|
+
* [#2303](https://github.com/ruby-grape/grape/pull/2302): Rack >= 1.3.0 - [@ericproulx](https://github.com/ericproulx).
|
10
|
+
* [#2301](https://github.com/ruby-grape/grape/pull/2301): Revisit GH workflows - [@ericproulx](https://github.com/ericproulx).
|
11
|
+
* [#2311](https://github.com/ruby-grape/grape/pull/2311): Fix tests by pinning rack-test to < 2.1 - [@duffn](https://github.com/duffn).
|
12
|
+
* [#2310](https://github.com/ruby-grape/grape/pull/2310): Fix YARD docs markdown rendering - [@duffn](https://github.com/duffn).
|
13
|
+
* [#2317](https://github.com/ruby-grape/grape/pull/2317): Remove maruku and rubocop-ast as direct development/testing dependencies - [@ericproulx](https://github.com/ericproulx).
|
14
|
+
* [#2292](https://github.com/ruby-grape/grape/pull/2292): Introduce Docker to local development - [@ericproulx](https://github.com/ericproulx).
|
15
|
+
* [#2325](https://github.com/ruby-grape/grape/pull/2325): Change edge test workflows only run on demand - [@dblock](https://github.com/dblock).
|
16
|
+
* [#2324](https://github.com/ruby-grape/grape/pull/2324): Expose default in the description dsl - [@dhruvCW](https://github.com/dhruvCW).
|
17
|
+
|
18
|
+
#### Fixes
|
19
|
+
|
20
|
+
* [#2299](https://github.com/ruby-grape/grape/pull/2299): Fix, do not use kwargs for empty args - [@dm1try](https://github.com/dm1try).
|
21
|
+
* [#2307](https://github.com/ruby-grape/grape/pull/2307): Fixed autoloading of InvalidValue - [@fixlr](https://github.com/fixlr).
|
22
|
+
* [#2315](https://github.com/ruby-grape/grape/pull/2315): Update rspec - [@ericproulx](https://github.com/ericproulx).
|
23
|
+
* [#2319](https://github.com/ruby-grape/grape/pull/2319): Update rubocop - [@ericproulx](https://github.com/ericproulx).
|
24
|
+
* [#2323](https://github.com/ruby-grape/grape/pull/2323): Fix using endless ranges for values parameter - [@dhruvCW](https://github.com/dhruvCW).
|
25
|
+
|
26
|
+
### 1.7.0 (2022/12/20)
|
2
27
|
|
3
28
|
#### Features
|
4
29
|
|
30
|
+
* [#2233](https://github.com/ruby-grape/grape/pull/2233): Added `do_not_document!` for disabling documentation to internal APIs - [@dnesteryuk](https://github.com/dnesteryuk).
|
31
|
+
* [#2235](https://github.com/ruby-grape/grape/pull/2235): Add support for Ruby 3.1 - [@petergoldstein](https://github.com/petergoldstein).
|
32
|
+
* [#2248](https://github.com/ruby-grape/grape/pull/2248): Upgraded to rspec 3.11.0 - [@dblock](https://github.com/dblock).
|
33
|
+
* [#2249](https://github.com/ruby-grape/grape/pull/2249): Split CI matrix, extract edge - [@dblock](https://github.com/dblock).
|
34
|
+
* [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock).
|
35
|
+
* [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed).
|
36
|
+
* [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock).
|
37
|
+
* [#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).
|
38
|
+
* [#2274](https://github.com/ruby-grape/grape/pull/2274): Error middleware support using rack util's symbols as status - [@dhruvCW](https://github.com/dhruvCW).
|
39
|
+
* [#2276](https://github.com/ruby-grape/grape/pull/2276): Fix exception super - [@ericproulx](https://github.com/ericproulx).
|
40
|
+
* [#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).
|
41
|
+
|
42
|
+
#### Fixes
|
43
|
+
|
44
|
+
* [#2263](https://github.com/ruby-grape/grape/pull/2263): Explicitly require `bigdecimal` and `date` - [@dblock](https://github.com/dblock).
|
45
|
+
* [#2222](https://github.com/ruby-grape/grape/pull/2222): Autoload types and validators - [@ericproulx](https://github.com/ericproulx).
|
46
|
+
* [#2232](https://github.com/ruby-grape/grape/pull/2232): Fix kwargs support in shared params definition - [@dm1try](https://github.com/dm1try).
|
47
|
+
* [#2229](https://github.com/ruby-grape/grape/pull/2229): Do not collect params in route settings - [@dnesteryuk](https://github.com/dnesteryuk).
|
48
|
+
* [#2234](https://github.com/ruby-grape/grape/pull/2234): Remove non-UTF8 characters from format before generating JSON error - [@bschmeck](https://github.com/bschmeck).
|
49
|
+
* [#2227](https://github.com/ruby-grape/grape/pull/2222): Rename `MissingGroupType` and `UnsupportedGroupType` exceptions - [@ericproulx](https://github.com/ericproulx).
|
50
|
+
* [#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).
|
51
|
+
* [#2250](https://github.com/ruby-grape/grape/pull/2250): Add deprecation warning for `UnsupportedGroupTypeError` and `MissingGroupTypeError` - [@ericproulx](https://github.com/ericproulx).
|
52
|
+
* [#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).
|
53
|
+
* [#2266](https://github.com/ruby-grape/grape/pull/2266): Fix code coverage - [@duffn](https://github.com/duffn).
|
54
|
+
* [#2284](https://github.com/ruby-grape/grape/pull/2284): Fix an unexpected backtick - [@zysend](https://github.com/zysend).
|
55
|
+
|
56
|
+
### 1.6.2 (2021/12/30)
|
57
|
+
|
5
58
|
#### Fixes
|
6
59
|
|
7
60
|
* [#2219](https://github.com/ruby-grape/grape/pull/2219): Revert the changes for autoloading provided in 1.6.1 - [@dm1try](https://github.com/dm1try).
|
data/CONTRIBUTING.md
CHANGED
@@ -23,6 +23,34 @@ git pull upstream master
|
|
23
23
|
git checkout -b my-feature-branch
|
24
24
|
```
|
25
25
|
|
26
|
+
### Docker
|
27
|
+
|
28
|
+
If you're familiar with [Docker](https://www.docker.com/), you can run everything through the following command:
|
29
|
+
|
30
|
+
```
|
31
|
+
docker-compose run --rm --build grape <command_and_parameters>
|
32
|
+
```
|
33
|
+
|
34
|
+
About the execution process:
|
35
|
+
- displays Ruby, Rubygems, Bundle and Gemfile version when starting:
|
36
|
+
```
|
37
|
+
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux-musl]
|
38
|
+
rubygems 3.4.12
|
39
|
+
Bundler version 2.4.1 (2022-12-24 commit f3175f033c)
|
40
|
+
Running default Gemfile
|
41
|
+
```
|
42
|
+
- keeps the gems to the latest possible version
|
43
|
+
- executes under `bundle exec`
|
44
|
+
|
45
|
+
Here are some examples:
|
46
|
+
|
47
|
+
- running all specs `docker-compose run --rm --build grape rspec`
|
48
|
+
- running rspec on a specific file `docker-compose run --rm --build grape rspec spec/:file_path`
|
49
|
+
- running task `docker-compose run --rm --build grape rake <task_name>`
|
50
|
+
- running rubocop `docker-compose run --rm --build grape rubocop`
|
51
|
+
- running all specs on a specific ruby version (e.g 2.7.7) `RUBY_VERSION=2.7.7 docker-compose run --rm --build grape rspec`
|
52
|
+
- running specs on a specific gemfile (e.g rails_7_0.gemfile) `docker-compose run -e GEMFILE=rails_7_0 --rm --build grape rspec`
|
53
|
+
|
26
54
|
#### Bundle Install and Test
|
27
55
|
|
28
56
|
Ensure that you can build the project and run tests.
|
@@ -58,6 +86,8 @@ Make sure that `bundle exec rake` completes without errors.
|
|
58
86
|
|
59
87
|
Document any external behavior in the [README](README.md).
|
60
88
|
|
89
|
+
You should also document code as necessary, using current code as examples. This project uses [YARD](https://yardoc.org/). You can run and preview the docs locally by [installing `yard`](https://yardoc.org/), running `yard server --reload` and view the docs at http://localhost:8808.
|
90
|
+
|
61
91
|
#### Update Changelog
|
62
92
|
|
63
93
|
Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account.
|
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.1.
|
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
|
|
@@ -545,12 +538,12 @@ end
|
|
545
538
|
|
546
539
|
class V1 < Grape::API
|
547
540
|
version 'v1'
|
548
|
-
mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::
|
541
|
+
mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::Entities::Status } }
|
549
542
|
end
|
550
543
|
|
551
544
|
class V2 < Grape::API
|
552
545
|
version 'v2'
|
553
|
-
mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::
|
546
|
+
mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::Entities::V2::Status } }
|
554
547
|
end
|
555
548
|
```
|
556
549
|
|
@@ -645,6 +638,7 @@ desc 'Returns your public timeline.' do
|
|
645
638
|
params API::Entities::Status.documentation
|
646
639
|
success API::Entities::Entity
|
647
640
|
failure [[401, 'Unauthorized', 'Entities::Error']]
|
641
|
+
default { code: 500, message: 'InvalidRequest', model: Entities::Error }
|
648
642
|
named 'My named route'
|
649
643
|
headers XAuthToken: {
|
650
644
|
description: 'Validates your identity',
|
@@ -669,8 +663,9 @@ end
|
|
669
663
|
|
670
664
|
* `detail`: A more enhanced description
|
671
665
|
* `params`: Define parameters directly from an `Entity`
|
672
|
-
* `success`: (former entity) The `Entity` to be used to present
|
673
|
-
* `failure`: (former http_codes) A definition of the used failure HTTP Codes and Entities
|
666
|
+
* `success`: (former entity) The `Entity` to be used to present the success response for this route.
|
667
|
+
* `failure`: (former http_codes) A definition of the used failure HTTP Codes and Entities.
|
668
|
+
* `default`: The definition and `Entity` used to present the default response for this route.
|
674
669
|
* `named`: A helper to give a route a name and find it with this name in the documentation Hash
|
675
670
|
* `headers`: A definition of the used Headers
|
676
671
|
* Other options can be found in [grape-swagger][grape-swagger]
|
@@ -1085,6 +1080,102 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d
|
|
1085
1080
|
}
|
1086
1081
|
````
|
1087
1082
|
|
1083
|
+
### Evaluate Given
|
1084
|
+
|
1085
|
+
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:
|
1086
|
+
|
1087
|
+
````ruby
|
1088
|
+
format :json
|
1089
|
+
|
1090
|
+
params do
|
1091
|
+
optional :child_id, type: Integer
|
1092
|
+
given :child_id do
|
1093
|
+
requires :father_id, type: Integer
|
1094
|
+
end
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
post 'child' do
|
1098
|
+
{ 'declared_params' => declared(params, evaluate_given: true) }
|
1099
|
+
end
|
1100
|
+
````
|
1101
|
+
|
1102
|
+
**Request**
|
1103
|
+
|
1104
|
+
````bash
|
1105
|
+
curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"father_id": 1}'
|
1106
|
+
````
|
1107
|
+
|
1108
|
+
**Response with evaluate_given:false**
|
1109
|
+
|
1110
|
+
````json
|
1111
|
+
{
|
1112
|
+
"declared_params": {
|
1113
|
+
"child_id": null,
|
1114
|
+
"father_id": 1
|
1115
|
+
}
|
1116
|
+
}
|
1117
|
+
````
|
1118
|
+
|
1119
|
+
**Response with evaluate_given:true**
|
1120
|
+
|
1121
|
+
````json
|
1122
|
+
{
|
1123
|
+
"declared_params": {
|
1124
|
+
"child_id": null
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
````
|
1128
|
+
|
1129
|
+
It also works on nested hashes:
|
1130
|
+
|
1131
|
+
````ruby
|
1132
|
+
format :json
|
1133
|
+
|
1134
|
+
params do
|
1135
|
+
requires :child, type: Hash do
|
1136
|
+
optional :child_id, type: Integer
|
1137
|
+
given :child_id do
|
1138
|
+
requires :father_id, type: Integer
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
post 'child' do
|
1144
|
+
{ 'declared_params' => declared(params, evaluate_given: true) }
|
1145
|
+
end
|
1146
|
+
````
|
1147
|
+
|
1148
|
+
**Request**
|
1149
|
+
|
1150
|
+
````bash
|
1151
|
+
curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"child": {"father_id": 1}}'
|
1152
|
+
````
|
1153
|
+
|
1154
|
+
**Response with evaluate_given:false**
|
1155
|
+
|
1156
|
+
````json
|
1157
|
+
{
|
1158
|
+
"declared_params": {
|
1159
|
+
"child": {
|
1160
|
+
"child_id": null,
|
1161
|
+
"father_id": 1
|
1162
|
+
}
|
1163
|
+
}
|
1164
|
+
}
|
1165
|
+
````
|
1166
|
+
|
1167
|
+
**Response with evaluate_given:true**
|
1168
|
+
|
1169
|
+
````json
|
1170
|
+
{
|
1171
|
+
"declared_params": {
|
1172
|
+
"child": {
|
1173
|
+
"child_id": null
|
1174
|
+
}
|
1175
|
+
}
|
1176
|
+
}
|
1177
|
+
````
|
1178
|
+
|
1088
1179
|
## Parameter Validation and Coercion
|
1089
1180
|
|
1090
1181
|
You can define validations and coercion options for your parameters using a `params` block.
|
@@ -1453,7 +1544,7 @@ resource :users do
|
|
1453
1544
|
end
|
1454
1545
|
```
|
1455
1546
|
|
1456
|
-
The value passed to `as` will be the key when calling `
|
1547
|
+
The value passed to `as` will be the key when calling `declared(params)`.
|
1457
1548
|
|
1458
1549
|
### Built-in Validators
|
1459
1550
|
|
@@ -1497,6 +1588,15 @@ params do
|
|
1497
1588
|
end
|
1498
1589
|
```
|
1499
1590
|
|
1591
|
+
Note endless ranges are also supported with ActiveSupport >= 6.0, but they require that the type be provided.
|
1592
|
+
|
1593
|
+
```ruby
|
1594
|
+
params do
|
1595
|
+
requires :minimum, type: Integer, values: 10..
|
1596
|
+
optional :maximum, type: Integer, values: ..10
|
1597
|
+
end
|
1598
|
+
```
|
1599
|
+
|
1500
1600
|
Note that *both* range endpoints have to be a `#kind_of?` your `:type` option (if you don't supply the `:type` option, it will be guessed to be equal to the class of the range's first endpoint). So the following is invalid:
|
1501
1601
|
|
1502
1602
|
```ruby
|
@@ -1742,10 +1842,10 @@ end
|
|
1742
1842
|
### Custom Validators
|
1743
1843
|
|
1744
1844
|
```ruby
|
1745
|
-
class AlphaNumeric < Grape::Validations::Base
|
1845
|
+
class AlphaNumeric < Grape::Validations::Validators::Base
|
1746
1846
|
def validate_param!(attr_name, params)
|
1747
1847
|
unless params[attr_name] =~ /\A[[:alnum:]]+\z/
|
1748
|
-
|
1848
|
+
raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: 'must consist of alpha-numeric characters'
|
1749
1849
|
end
|
1750
1850
|
end
|
1751
1851
|
end
|
@@ -1760,10 +1860,10 @@ end
|
|
1760
1860
|
You can also create custom classes that take parameters.
|
1761
1861
|
|
1762
1862
|
```ruby
|
1763
|
-
class Length < Grape::Validations::Base
|
1863
|
+
class Length < Grape::Validations::Validators::Base
|
1764
1864
|
def validate_param!(attr_name, params)
|
1765
1865
|
unless params[attr_name].length <= @option
|
1766
|
-
|
1866
|
+
raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
|
1767
1867
|
end
|
1768
1868
|
end
|
1769
1869
|
end
|
@@ -1778,7 +1878,7 @@ end
|
|
1778
1878
|
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
1879
|
|
1780
1880
|
```ruby
|
1781
|
-
class Admin < Grape::Validations::Base
|
1881
|
+
class Admin < Grape::Validations::Validators::Base
|
1782
1882
|
def validate(request)
|
1783
1883
|
# return if the param we are checking was not in request
|
1784
1884
|
# @attrs is a list containing the attribute we are currently validating
|
@@ -1789,7 +1889,7 @@ class Admin < Grape::Validations::Base
|
|
1789
1889
|
return unless @option
|
1790
1890
|
# check if user is admin or not
|
1791
1891
|
# as an example get a token from request and check if it's admin or not
|
1792
|
-
|
1892
|
+
raise Grape::Exceptions::Validation.new params: @attrs, message: 'Can not set admin-only field.' unless request.headers['X-Access-Token'] == 'admin'
|
1793
1893
|
end
|
1794
1894
|
end
|
1795
1895
|
```
|
@@ -2248,6 +2348,18 @@ params do
|
|
2248
2348
|
end
|
2249
2349
|
```
|
2250
2350
|
|
2351
|
+
If documentation isn't needed (for instance, it is an internal API), documentation can be disabled.
|
2352
|
+
|
2353
|
+
```ruby
|
2354
|
+
class API < Grape::API
|
2355
|
+
do_not_document!
|
2356
|
+
|
2357
|
+
# endpoints...
|
2358
|
+
end
|
2359
|
+
```
|
2360
|
+
|
2361
|
+
In this case, Grape won't create objects related to documentation which are retained in RAM forever.
|
2362
|
+
|
2251
2363
|
## Cookies
|
2252
2364
|
|
2253
2365
|
You can set, get and delete your cookies very simply using `cookies` method.
|
@@ -3239,6 +3351,17 @@ end
|
|
3239
3351
|
|
3240
3352
|
Use `body false` to return `204 No Content` without any data or content-type.
|
3241
3353
|
|
3354
|
+
If you want to empty the body with an HTTP status code other than `204 No Content`, you can override the status code after specifying `body false` as follows
|
3355
|
+
|
3356
|
+
```ruby
|
3357
|
+
class API < Grape::API
|
3358
|
+
get '/' do
|
3359
|
+
body false
|
3360
|
+
status 304
|
3361
|
+
end
|
3362
|
+
end
|
3363
|
+
```
|
3364
|
+
|
3242
3365
|
You can also set the response to a file with `sendfile`. This works with the
|
3243
3366
|
[Rack::Sendfile](https://www.rubydoc.info/gems/rack/Rack/Sendfile) middleware to optimally send
|
3244
3367
|
the file through your web server software.
|
@@ -3701,7 +3824,7 @@ Use `rack-test` and define your API as `app`.
|
|
3701
3824
|
You can test a Grape API with RSpec by making HTTP requests and examining the response.
|
3702
3825
|
|
3703
3826
|
```ruby
|
3704
|
-
|
3827
|
+
|
3705
3828
|
|
3706
3829
|
describe Twitter::API do
|
3707
3830
|
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
|
data/grape.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_runtime_dependency 'builder'
|
25
25
|
s.add_runtime_dependency 'dry-types', '>= 1.1'
|
26
26
|
s.add_runtime_dependency 'mustermann-grape', '~> 1.0.0'
|
27
|
-
s.add_runtime_dependency 'rack', '>= 1.3.0'
|
27
|
+
s.add_runtime_dependency 'rack', '>= 1.3.0', '< 3'
|
28
28
|
s.add_runtime_dependency 'rack-accept'
|
29
29
|
|
30
30
|
s.files = %w[CHANGELOG.md CONTRIBUTING.md README.md grape.png UPGRADING.md LICENSE]
|
@@ -32,5 +32,5 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.files += Dir['lib/**/*']
|
33
33
|
s.test_files = Dir['spec/**/*']
|
34
34
|
s.require_paths = ['lib']
|
35
|
-
s.required_ruby_version = '>= 2.
|
35
|
+
s.required_ruby_version = '>= 2.6.0'
|
36
36
|
end
|
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) }
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-types'
|
4
|
+
|
5
|
+
module Grape
|
6
|
+
module DryTypes
|
7
|
+
# Call +Dry.Types()+ to add all registered types to +DryTypes+ which is
|
8
|
+
# a container in this case. Check documentation for more information
|
9
|
+
# https://dry-rb.org/gems/dry-types/1.2/getting-started/
|
10
|
+
include Dry.Types()
|
11
|
+
end
|
12
|
+
end
|
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
|
@@ -113,7 +98,8 @@ module Grape
|
|
113
98
|
:produces,
|
114
99
|
:consumes,
|
115
100
|
:security,
|
116
|
-
:tags
|
101
|
+
:tags,
|
102
|
+
:default
|
117
103
|
)
|
118
104
|
config_context.define_singleton_method(:configuration) do
|
119
105
|
endpoint_configuration
|
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
|
@@ -91,7 +95,7 @@ module Grape
|
|
91
95
|
return yield if has_passed_children
|
92
96
|
|
93
97
|
key = params_nested_path[0]
|
94
|
-
key += "[#{params_nested_path[1
|
98
|
+
key += "[#{params_nested_path[1..].join('][')}]" if params_nested_path.size > 1
|
95
99
|
|
96
100
|
route_options_params = options[:route_options][:params] || {}
|
97
101
|
type = route_options_params.dig(key, :type)
|