grape 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +69 -0
- data/CONTRIBUTING.md +2 -10
- data/README.md +106 -43
- data/UPGRADING.md +90 -1
- data/grape.gemspec +4 -4
- data/lib/grape/api/instance.rb +51 -73
- data/lib/grape/api.rb +56 -89
- data/lib/grape/cookies.rb +31 -25
- data/lib/grape/dry_types.rb +48 -4
- data/lib/grape/dsl/callbacks.rb +8 -58
- data/lib/grape/dsl/desc.rb +8 -67
- data/lib/grape/dsl/headers.rb +1 -1
- data/lib/grape/dsl/helpers.rb +60 -65
- data/lib/grape/dsl/inside_route.rb +26 -61
- data/lib/grape/dsl/logger.rb +3 -6
- data/lib/grape/dsl/middleware.rb +22 -40
- data/lib/grape/dsl/parameters.rb +10 -19
- data/lib/grape/dsl/request_response.rb +136 -139
- data/lib/grape/dsl/routing.rb +230 -194
- data/lib/grape/dsl/settings.rb +22 -134
- data/lib/grape/dsl/validations.rb +37 -45
- data/lib/grape/endpoint.rb +91 -126
- data/lib/grape/error_formatter/base.rb +2 -0
- data/lib/grape/exceptions/base.rb +1 -1
- data/lib/grape/exceptions/conflicting_types.rb +11 -0
- data/lib/grape/exceptions/invalid_parameters.rb +11 -0
- data/lib/grape/exceptions/missing_group_type.rb +0 -2
- data/lib/grape/exceptions/too_deep_parameters.rb +11 -0
- data/lib/grape/exceptions/unknown_auth_strategy.rb +11 -0
- data/lib/grape/exceptions/unknown_params_builder.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +0 -2
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +2 -5
- data/lib/grape/extensions/hash.rb +2 -1
- data/lib/grape/extensions/hashie/mash.rb +3 -5
- data/lib/grape/locale/en.yml +44 -44
- data/lib/grape/middleware/auth/base.rb +11 -32
- data/lib/grape/middleware/auth/dsl.rb +22 -29
- data/lib/grape/middleware/base.rb +30 -11
- data/lib/grape/middleware/error.rb +14 -32
- data/lib/grape/middleware/formatter.rb +40 -72
- data/lib/grape/middleware/stack.rb +28 -38
- data/lib/grape/middleware/versioner/accept_version_header.rb +2 -4
- data/lib/grape/middleware/versioner/base.rb +30 -56
- data/lib/grape/middleware/versioner/header.rb +2 -2
- data/lib/grape/middleware/versioner/param.rb +2 -3
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/namespace.rb +11 -0
- data/lib/grape/params_builder/base.rb +20 -0
- data/lib/grape/params_builder/hash.rb +11 -0
- data/lib/grape/params_builder/hash_with_indifferent_access.rb +11 -0
- data/lib/grape/params_builder/hashie_mash.rb +11 -0
- data/lib/grape/params_builder.rb +32 -0
- data/lib/grape/request.rb +161 -22
- data/lib/grape/router/route.rb +1 -1
- data/lib/grape/router.rb +27 -8
- data/lib/grape/util/api_description.rb +56 -0
- data/lib/grape/util/base_inheritable.rb +5 -2
- data/lib/grape/util/inheritable_setting.rb +7 -0
- data/lib/grape/util/media_type.rb +1 -1
- data/lib/grape/util/registry.rb +1 -1
- data/lib/grape/validations/contract_scope.rb +2 -2
- data/lib/grape/validations/params_documentation.rb +50 -0
- data/lib/grape/validations/params_scope.rb +46 -56
- data/lib/grape/validations/types/array_coercer.rb +2 -3
- data/lib/grape/validations/types/dry_type_coercer.rb +4 -11
- data/lib/grape/validations/types/primitive_coercer.rb +1 -28
- data/lib/grape/validations/types.rb +10 -25
- data/lib/grape/validations/validators/base.rb +2 -9
- data/lib/grape/validations/validators/except_values_validator.rb +1 -1
- data/lib/grape/validations/validators/presence_validator.rb +1 -1
- data/lib/grape/validations/validators/regexp_validator.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +18 -9
- metadata +35 -20
- data/lib/grape/api/helpers.rb +0 -9
- data/lib/grape/dsl/api.rb +0 -19
- data/lib/grape/dsl/configuration.rb +0 -15
- data/lib/grape/error_formatter/jsonapi.rb +0 -7
- data/lib/grape/http/headers.rb +0 -56
- data/lib/grape/middleware/helpers.rb +0 -12
- data/lib/grape/parser/jsonapi.rb +0 -7
- data/lib/grape/types/invalid_value.rb +0 -8
- data/lib/grape/util/lazy/object.rb +0 -45
- data/lib/grape/util/strict_hash_configuration.rb +0 -108
- data/lib/grape/validations/attributes_doc.rb +0 -60
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 919d93a2a8cd39c07b1a043fb342cbecdf5ce4a85b7696188d2de629f92b02a1
|
|
4
|
+
data.tar.gz: c33240607db8c00cba0fc1d5cf5d9c50809c561d3c29b10f246fe9e96423d277
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: baf576a03f0a56114032b12d842964d8fb5587de44bdded21c2faecca9a2da3bf7f8eb36aa7a8cec4b4b9b4904ab92ab9763045688452e88f891fc7bf781e527
|
|
7
|
+
data.tar.gz: 48dcc1cab168fd88fd7b839da6c0bbaecc8108c6eac62cc9e1f0f2c09c3e9fd5db2756fa246fce2fb2822c92eff5dc8ef6e2b694edf9b08e244b7c0749fb6633
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,71 @@
|
|
|
1
|
+
### 3.0.0 (2025-11-15)
|
|
2
|
+
|
|
3
|
+
#### Features
|
|
4
|
+
|
|
5
|
+
* [#2572](https://github.com/ruby-grape/grape/pull/2572): Drop support ruby 2.7 and active_support 6.1 - [@ericproulx](https://github.com/ericproulx).
|
|
6
|
+
* [#2573](https://github.com/ruby-grape/grape/pull/2573): Clean up deprecated code - [@ericproulx](https://github.com/ericproulx).
|
|
7
|
+
* [#2575](https://github.com/ruby-grape/grape/pull/2575): Refactor Api description class - [@ericproulx](https://github.com/ericproulx).
|
|
8
|
+
* [#2577](https://github.com/ruby-grape/grape/pull/2577): Deprecate `return` in endpoint execution - [@ericproulx](https://github.com/ericproulx).
|
|
9
|
+
* [#2580](https://github.com/ruby-grape/grape/pull/2580): Refactor endpoint helpers and error middleware integration - [@ericproulx](https://github.com/ericproulx).
|
|
10
|
+
* [#2581](https://github.com/ruby-grape/grape/pull/2581): Delegate `to_s` in Grape::API::Instance - [@ericproulx](https://github.com/ericproulx).
|
|
11
|
+
* [#2582](https://github.com/ruby-grape/grape/pull/2582): Fix leaky slash when normalizing - [@ericproulx](https://github.com/ericproulx).
|
|
12
|
+
* [#2583](https://github.com/ruby-grape/grape/pull/2583): Optimize api parameter documentation and memory usage - [@ericproulx](https://github.com/ericproulx).
|
|
13
|
+
* [#2589](https://github.com/ruby-grape/grape/pull/2589): Replace `send` by `__send__` in codebase - [@ericproulx](https://github.com/ericproulx).
|
|
14
|
+
* [#2598](https://github.com/ruby-grape/grape/pull/2598): Refactor settings DSL to use explicit methods instead of dynamic generation - [@ericproulx](https://github.com/ericproulx).
|
|
15
|
+
* [#2599](https://github.com/ruby-grape/grape/pull/2599): Simplify settings DSL get_or_set method and optimize logger implementation - [@ericproulx](https://github.com/ericproulx).
|
|
16
|
+
* [#2600](https://github.com/ruby-grape/grape/pull/2600): Refactor versioner middleware: simplify base class and improve consistency - [@ericproulx](https://github.com/ericproulx).
|
|
17
|
+
* [#2601](https://github.com/ruby-grape/grape/pull/2601): Refactor route_setting internal usage to use inheritable_setting.route for improved consistency and performance - [@ericproulx](https://github.com/ericproulx).
|
|
18
|
+
* [#2602](https://github.com/ruby-grape/grape/pull/2602): Remove `namespace_reverse_stackable` from public DSL interface and use direct inheritable_setting access - [@ericproulx](https://github.com/ericproulx).
|
|
19
|
+
* [#2603](https://github.com/ruby-grape/grape/pull/2603): Remove `namespace_stackable_with_hash` from public interface and move to internal InheritableSetting - [@ericproulx](https://github.com/ericproulx).
|
|
20
|
+
* [#2604](https://github.com/ruby-grape/grape/pull/2604): Enable branch coverage - [@ericproulx](https://github.com/ericproulx).
|
|
21
|
+
* [#2605](https://github.com/ruby-grape/grape/pull/2605): Add Rack 3.2 support with new gemfile and CI integration - [@ericproulx](https://github.com/ericproulx).
|
|
22
|
+
* [#2607](https://github.com/ruby-grape/grape/pull/2607): Remove namespace_stackable and namespace_inheritable from public API - [@ericproulx](https://github.com/ericproulx).
|
|
23
|
+
* [#2615](https://github.com/ruby-grape/grape/pull/2615): Remove manual toc and tod danger check - [@alexanderadam](https://github.com/alexanderadam).
|
|
24
|
+
* [#2612](https://github.com/ruby-grape/grape/pull/2612): Avoid multiple mount pollution - [@alexanderadam](https://github.com/alexanderadam).
|
|
25
|
+
* [#2617](https://github.com/ruby-grape/grape/pull/2617): Migrate from `ActiveSupport::Configurable` to `Dry::Configurable` - [@ericproulx](https://github.com/ericproulx).
|
|
26
|
+
* [#2618](https://github.com/ruby-grape/grape/pull/2618): Modernize argument delegation for Ruby 3+ compatibility - [@ericproulx](https://github.com/ericproulx).
|
|
27
|
+
* [#2623](https://github.com/ruby-grape/grape/pull/2623): Refactor coercer caching to use `Grape::Util::Cache` - [@ericproulx](https://github.com/ericproulx).
|
|
28
|
+
|
|
29
|
+
#### Fixes
|
|
30
|
+
|
|
31
|
+
* [#2586](https://github.com/ruby-grape/grape/pull/2586): Limit helpers DSL public scope - [@ericproulx](https://github.com/ericproulx).
|
|
32
|
+
* [#2588](https://github.com/ruby-grape/grape/pull/2588): Fix defaut format regression on */* - [@ericproulx](https://github.com/ericproulx).
|
|
33
|
+
* [#2593](https://github.com/ruby-grape/grape/pull/2593): Fix warning message when overriding global registry key - [@ericproulx](https://github.com/ericproulx).
|
|
34
|
+
* [#2594](https://github.com/ruby-grape/grape/pull/2594): Fix routes memoization - [@ericproulx](https://github.com/ericproulx).
|
|
35
|
+
* [#2595](https://github.com/ruby-grape/grape/pull/2595): Keep `within_namespace` as part of our internal api - [@ericproulx](https://github.com/ericproulx).
|
|
36
|
+
* [#2596](https://github.com/ruby-grape/grape/pull/2596): Remove `namespace_reverse_stackable_with_hash` from public scope - [@ericproulx](https://github.com/ericproulx).
|
|
37
|
+
* [#2621](https://github.com/ruby-grape/grape/pull/2621): Update upgrading notes regarding `return` usage and simplify endpoint execution - [@ericproulx](https://github.com/ericproulx).
|
|
38
|
+
* [#2622](https://github.com/ruby-grape/grape/pull/2622): Use `require_relative` instead of `$LOAD_PATH` in gemspec - [@ericproulx](https://github.com/ericproulx).
|
|
39
|
+
|
|
40
|
+
### 2.4.0 (2025-06-18)
|
|
41
|
+
|
|
42
|
+
#### Features
|
|
43
|
+
|
|
44
|
+
* [#2532](https://github.com/ruby-grape/grape/pull/2532): Update RuboCop 1.71.2 - [@ericproulx](https://github.com/ericproulx).
|
|
45
|
+
* [#2535](https://github.com/ruby-grape/grape/pull/2535): Delegate calls to inner objects - [@ericproulx](https://github.com/ericproulx).
|
|
46
|
+
* [#2537](https://github.com/ruby-grape/grape/pull/2537): Use activesupport `try` pattern - [@ericproulx](https://github.com/ericproulx).
|
|
47
|
+
* [#2536](https://github.com/ruby-grape/grape/pull/2536): Update normalize_path like Rails - [@ericproulx](https://github.com/ericproulx).
|
|
48
|
+
* [#2540](https://github.com/ruby-grape/grape/pull/2540): Introduce params builder with symbolized short name - [@ericproulx](https://github.com/ericproulx).
|
|
49
|
+
* [#2550](https://github.com/ruby-grape/grape/pull/2550): Drop ActiveSupport 6.0 - [@ericproulx](https://github.com/ericproulx).
|
|
50
|
+
* [#2549](https://github.com/ruby-grape/grape/pull/2549): Delegate cookies management to `Grape::Request` - [@ericproulx](https://github.com/ericproulx).
|
|
51
|
+
* [#2554](https://github.com/ruby-grape/grape/pull/2554): Remove `Grape::Http::Headers` and `Grape::Util::Lazy::Object` - [@ericproulx](https://github.com/ericproulx).
|
|
52
|
+
* [#2556](https://github.com/ruby-grape/grape/pull/2556): Remove unused `Grape::Request::DEFAULT_PARAMS_BUILDER` constant - [@eriklovmo](https://github.com/eriklovmo).
|
|
53
|
+
* [#2558](https://github.com/ruby-grape/grape/pull/2558): Add Ruby's option `enable_frozen_string_literal` in CI - [@ericproulx](https://github.com/ericproulx).
|
|
54
|
+
* [#2557](https://github.com/ruby-grape/grape/pull/2557): Add `lint!` - [@ericproulx](https://github.com/ericproulx).
|
|
55
|
+
* [#2561](https://github.com/ruby-grape/grape/pull/2561): Optimize hash alloc for middleware's default options - [@ericproulx](https://github.com/ericproulx).
|
|
56
|
+
* [#2563](https://github.com/ruby-grape/grape/pull/2563): Update `Grape::Middleware::Auth::Base` - [@ericproulx](https://github.com/ericproulx).
|
|
57
|
+
* [#2571](https://github.com/ruby-grape/grape/pull/2571): Update RuboCop 1.75.8 - [@pieterocp](https://github.com/pieterocp).
|
|
58
|
+
|
|
59
|
+
#### Fixes
|
|
60
|
+
|
|
61
|
+
* [#2538](https://github.com/ruby-grape/grape/pull/2538): Fix validating nested json array params - [@mohammednasser-32](https://github.com/mohammednasser-32).
|
|
62
|
+
* [#2543](https://github.com/ruby-grape/grape/pull/2543): Fix array allocation on mount - [@ericproulx](https://github.com/ericproulx).
|
|
63
|
+
* [#2546](https://github.com/ruby-grape/grape/pull/2546): Fix middleware with keywords - [@ericproulx](https://github.com/ericproulx).
|
|
64
|
+
* [#2547](https://github.com/ruby-grape/grape/pull/2547): Remove jsonapi related code - [@ericproulx](https://github.com/ericproulx).
|
|
65
|
+
* [#2548](https://github.com/ruby-grape/grape/pull/2548): Formatting from header acts like versioning from header - [@ericproulx](https://github.com/ericproulx).
|
|
66
|
+
* [#2552](https://github.com/ruby-grape/grape/pull/2552): Fix declared params optional array - [@ericproulx](https://github.com/ericproulx).
|
|
67
|
+
* [#2553](https://github.com/ruby-grape/grape/pull/2553): Improve performance of query params parsing - [@ericproulx](https://github.com/ericproulx).
|
|
68
|
+
|
|
1
69
|
### 2.3.0 (2025-02-08)
|
|
2
70
|
|
|
3
71
|
#### Features
|
|
@@ -1136,3 +1204,4 @@
|
|
|
1136
1204
|
### 0.1.0 (2010/11/13)
|
|
1137
1205
|
|
|
1138
1206
|
* Initial public release - [@mbleigh](https://github.com/mbleigh).
|
|
1207
|
+
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Contributing to Grape
|
|
2
2
|
=====================
|
|
3
3
|
|
|
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).
|
|
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).
|
|
5
5
|
|
|
6
6
|
#### Fork the Project
|
|
7
7
|
|
|
@@ -48,7 +48,7 @@ Here are some examples:
|
|
|
48
48
|
- running rspec on a specific file `docker-compose run --rm --build grape rspec spec/:file_path`
|
|
49
49
|
- running task `docker-compose run --rm --build grape rake <task_name>`
|
|
50
50
|
- running rubocop `docker-compose run --rm --build grape rubocop`
|
|
51
|
-
- running all specs on a specific ruby version (e.g
|
|
51
|
+
- running all specs on a specific ruby version (e.g 3.0) `RUBY_VERSION=3.0 docker-compose run --rm --build grape rspec`
|
|
52
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
53
|
|
|
54
54
|
#### Bundle Install and Test
|
|
@@ -60,14 +60,6 @@ bundle install
|
|
|
60
60
|
bundle exec rake
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Run tests against all supported versions of Rails.
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
gem install appraisal
|
|
67
|
-
appraisal install
|
|
68
|
-
appraisal rake spec
|
|
69
|
-
```
|
|
70
|
-
|
|
71
63
|
#### Write Tests
|
|
72
64
|
|
|
73
65
|
Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [spec/grape](spec/grape).
|
data/README.md
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/grape)
|
|
4
|
-
[](https://codeclimate.com/github/ruby-grape/grape)
|
|
4
|
+
[](https://github.com/ruby-grape/grape/actions/workflows/test.yml)
|
|
6
5
|
[](https://coveralls.io/github/ruby-grape/grape?branch=master)
|
|
7
|
-
[](https://inch-ci.org/github/ruby-grape/grape)
|
|
8
|
-
[](https://gitter.im/ruby-grape/grape?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
9
6
|
|
|
10
7
|
## Table of Contents
|
|
11
8
|
|
|
@@ -31,6 +28,8 @@
|
|
|
31
28
|
- [Header](#header)
|
|
32
29
|
- [Accept-Version Header](#accept-version-header)
|
|
33
30
|
- [Param](#param)
|
|
31
|
+
- [Linting](#linting)
|
|
32
|
+
- [Bug in Rack::ETag under Rack 3.X](#bug-in-racketag-under-rack-3x)
|
|
34
33
|
- [Describing Methods](#describing-methods)
|
|
35
34
|
- [Configuration](#configuration)
|
|
36
35
|
- [Parameters](#parameters)
|
|
@@ -138,13 +137,17 @@
|
|
|
138
137
|
- [Reloading API Changes in Development](#reloading-api-changes-in-development)
|
|
139
138
|
- [Reloading in Rack Applications](#reloading-in-rack-applications)
|
|
140
139
|
- [Reloading in Rails Applications](#reloading-in-rails-applications)
|
|
140
|
+
- [Rails 7+ (Zeitwerk)](#rails-7-zeitwerk)
|
|
141
|
+
- [Rails 6 and Earlier](#rails-6-and-earlier)
|
|
141
142
|
- [Performance Monitoring](#performance-monitoring)
|
|
142
143
|
- [Active Support Instrumentation](#active-support-instrumentation)
|
|
143
|
-
- [
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
- [Hook Points](#hook-points)
|
|
145
|
+
- [endpoint_run.grape](#endpoint_rungrape)
|
|
146
|
+
- [endpoint_render.grape](#endpoint_rendergrape)
|
|
147
|
+
- [endpoint_run_filters.grape](#endpoint_run_filtersgrape)
|
|
148
|
+
- [endpoint_run_validators.grape](#endpoint_run_validatorsgrape)
|
|
149
|
+
- [format_response.grape](#format_responsegrape)
|
|
150
|
+
- [Subscribe to Hooks](#subscribe-to-hooks)
|
|
148
151
|
- [Monitoring Products](#monitoring-products)
|
|
149
152
|
- [Contributing to Grape](#contributing-to-grape)
|
|
150
153
|
- [Security](#security)
|
|
@@ -157,14 +160,13 @@ Grape is a REST-like API framework for Ruby. It's designed to run on Rack or com
|
|
|
157
160
|
|
|
158
161
|
## Stable Release
|
|
159
162
|
|
|
160
|
-
You're reading the documentation for the
|
|
161
|
-
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
|
163
|
+
You're reading the documentation for the stable release of Grape, 3.0.0.
|
|
162
164
|
|
|
163
165
|
## Project Resources
|
|
164
166
|
|
|
165
167
|
* [Grape Website](http://www.ruby-grape.org)
|
|
166
168
|
* [Documentation](http://www.rubydoc.info/gems/grape)
|
|
167
|
-
* Need help?
|
|
169
|
+
* Need help? [Open an Issue](https://github.com/ruby-grape/grape/issues)
|
|
168
170
|
* [Follow us on Twitter](https://twitter.com/grapeframework)
|
|
169
171
|
|
|
170
172
|
## Grape for Enterprise
|
|
@@ -175,7 +177,7 @@ The maintainers of Grape are working with Tidelift to deliver commercial support
|
|
|
175
177
|
|
|
176
178
|
## Installation
|
|
177
179
|
|
|
178
|
-
Ruby
|
|
180
|
+
Ruby 3.0 or newer is required.
|
|
179
181
|
|
|
180
182
|
Grape is available as a gem, to install it run:
|
|
181
183
|
|
|
@@ -272,7 +274,7 @@ Grape's [deprecator](https://api.rubyonrails.org/v7.1.0/classes/ActiveSupport/De
|
|
|
272
274
|
### All
|
|
273
275
|
|
|
274
276
|
|
|
275
|
-
By default Grape will compile the routes on the first route, it is possible to pre-load routes using the `compile!` method.
|
|
277
|
+
By default Grape will compile the routes on the first route, but it is possible to pre-load routes using the `compile!` method.
|
|
276
278
|
|
|
277
279
|
```ruby
|
|
278
280
|
Twitter::API.compile!
|
|
@@ -653,6 +655,27 @@ version 'v1', using: :param, parameter: 'v'
|
|
|
653
655
|
curl http://localhost:9292/statuses/public_timeline?v=v1
|
|
654
656
|
|
|
655
657
|
|
|
658
|
+
## Linting
|
|
659
|
+
|
|
660
|
+
You can check whether your API is in conformance with the [Rack's specification](https://github.com/rack/rack/blob/main/SPEC.rdoc) by calling `lint!` at the API level or through [configuration](#configuration).
|
|
661
|
+
|
|
662
|
+
```ruby
|
|
663
|
+
class Api < Grape::API
|
|
664
|
+
lint!
|
|
665
|
+
end
|
|
666
|
+
```
|
|
667
|
+
```ruby
|
|
668
|
+
Grape.configure do |config|
|
|
669
|
+
config.lint = true
|
|
670
|
+
end
|
|
671
|
+
```
|
|
672
|
+
```ruby
|
|
673
|
+
Grape.config.lint = true
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### Bug in Rack::ETag under Rack 3.X
|
|
677
|
+
If you're using Rack 3.X and the `Rack::Etag` middleware (used by [Rails](https://guides.rubyonrails.org/rails_on_rack.html#inspecting-middleware-stack)), a [bug](https://github.com/rack/rack/pull/2324) related to linting has been fixed in [3.1.13](https://github.com/rack/rack/blob/v3.1.13/CHANGELOG.md#3113---2025-04-13) and [3.0.15](https://github.com/rack/rack/blob/v3.1.13/CHANGELOG.md#3015---2025-04-13) respectively.
|
|
678
|
+
|
|
656
679
|
## Describing Methods
|
|
657
680
|
|
|
658
681
|
You can add a description to API methods and namespaces. The description would be used by [grape-swagger][grape-swagger] to generate swagger compliant documentation.
|
|
@@ -719,10 +742,13 @@ For example, for the `param_builder`, the following code could run in an initial
|
|
|
719
742
|
|
|
720
743
|
```ruby
|
|
721
744
|
Grape.configure do |config|
|
|
722
|
-
config.param_builder =
|
|
745
|
+
config.param_builder = :hashie_mash
|
|
723
746
|
end
|
|
724
747
|
```
|
|
725
748
|
|
|
749
|
+
Available parameter builders are `:hash`, `:hash_with_indifferent_access`, and `:hashie_mash`.
|
|
750
|
+
See [params_builder](lib/grape/params_builder).
|
|
751
|
+
|
|
726
752
|
You can also configure a single API:
|
|
727
753
|
|
|
728
754
|
```ruby
|
|
@@ -789,7 +815,7 @@ By default parameters are available as `ActiveSupport::HashWithIndifferentAccess
|
|
|
789
815
|
|
|
790
816
|
```ruby
|
|
791
817
|
class API < Grape::API
|
|
792
|
-
|
|
818
|
+
build_with :hashie_mash
|
|
793
819
|
|
|
794
820
|
params do
|
|
795
821
|
optional :color, type: String
|
|
@@ -803,16 +829,15 @@ The class can also be overridden on individual parameter blocks using `build_wit
|
|
|
803
829
|
|
|
804
830
|
```ruby
|
|
805
831
|
params do
|
|
806
|
-
build_with
|
|
832
|
+
build_with :hash
|
|
807
833
|
optional :color, type: String
|
|
808
834
|
end
|
|
809
835
|
```
|
|
810
836
|
|
|
811
|
-
Or globally with the [Configuration](#configuration) `Grape.configure.param_builder`.
|
|
812
|
-
|
|
813
837
|
In the example above, `params["color"]` will return `nil` since `params` is a plain `Hash`.
|
|
814
838
|
|
|
815
|
-
Available parameter builders are
|
|
839
|
+
Available parameter builders are `:hash`, `:hash_with_indifferent_access`, and `:hashie_mash`.
|
|
840
|
+
See [params_builder](lib/grape/params_builder).
|
|
816
841
|
|
|
817
842
|
### Declared
|
|
818
843
|
|
|
@@ -4055,6 +4080,25 @@ Use [grape-reload](https://github.com/AlexYankee/grape-reload).
|
|
|
4055
4080
|
|
|
4056
4081
|
### Reloading in Rails Applications
|
|
4057
4082
|
|
|
4083
|
+
#### Rails 7+ (Zeitwerk)
|
|
4084
|
+
|
|
4085
|
+
Rails 7+ uses [Zeitwerk](https://github.com/fxn/zeitwerk) as the default autoloader, which automatically handles reloading of code in development mode without any additional configuration.
|
|
4086
|
+
|
|
4087
|
+
If your API files are in `app/api`, Zeitwerk will automatically autoload and reload them. No additional configuration is needed.
|
|
4088
|
+
|
|
4089
|
+
If you encounter issues with reloading, ensure that:
|
|
4090
|
+
|
|
4091
|
+
1. Your API files follow Zeitwerk naming conventions (file names should match class names).
|
|
4092
|
+
2. The `config.enable_reloading` is set to `true` in `config/environments/development.rb` (this is the default).
|
|
4093
|
+
|
|
4094
|
+
For troubleshooting autoloading issues, have a look at the [Rails documentation](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#troubleshooting).
|
|
4095
|
+
|
|
4096
|
+
See the [Rails Autoloading and Reloading Constants guide](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html) for more information.
|
|
4097
|
+
|
|
4098
|
+
#### Rails 6 and Earlier
|
|
4099
|
+
|
|
4100
|
+
For Rails versions before 7, you need to configure reloading manually.
|
|
4101
|
+
|
|
4058
4102
|
Add API paths to `config/application.rb`.
|
|
4059
4103
|
|
|
4060
4104
|
```ruby
|
|
@@ -4073,28 +4117,12 @@ if Rails.env.development?
|
|
|
4073
4117
|
api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do
|
|
4074
4118
|
Rails.application.reload_routes!
|
|
4075
4119
|
end
|
|
4076
|
-
|
|
4120
|
+
ActiveSupport::Reloader.to_prepare do
|
|
4077
4121
|
api_reloader.execute_if_updated
|
|
4078
4122
|
end
|
|
4079
4123
|
end
|
|
4080
4124
|
```
|
|
4081
4125
|
|
|
4082
|
-
For Rails >= 5.1.4, change this:
|
|
4083
|
-
|
|
4084
|
-
```ruby
|
|
4085
|
-
ActionDispatch::Callbacks.to_prepare do
|
|
4086
|
-
api_reloader.execute_if_updated
|
|
4087
|
-
end
|
|
4088
|
-
```
|
|
4089
|
-
|
|
4090
|
-
to this:
|
|
4091
|
-
|
|
4092
|
-
```ruby
|
|
4093
|
-
ActiveSupport::Reloader.to_prepare do
|
|
4094
|
-
api_reloader.execute_if_updated
|
|
4095
|
-
end
|
|
4096
|
-
```
|
|
4097
|
-
|
|
4098
4126
|
See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request/4368838#4368838) for more information.
|
|
4099
4127
|
|
|
4100
4128
|
## Performance Monitoring
|
|
@@ -4103,27 +4131,30 @@ See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-
|
|
|
4103
4131
|
|
|
4104
4132
|
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.
|
|
4105
4133
|
|
|
4106
|
-
The following are currently supported:
|
|
4107
4134
|
|
|
4108
|
-
####
|
|
4135
|
+
#### Hook Points
|
|
4136
|
+
|
|
4137
|
+
The following hook points are currently supported:
|
|
4138
|
+
|
|
4139
|
+
##### endpoint_run.grape
|
|
4109
4140
|
|
|
4110
4141
|
The main execution of an endpoint, includes filters and rendering.
|
|
4111
4142
|
|
|
4112
4143
|
* *endpoint* - The endpoint instance
|
|
4113
4144
|
|
|
4114
|
-
|
|
4145
|
+
##### endpoint_render.grape
|
|
4115
4146
|
|
|
4116
4147
|
The execution of the main content block of the endpoint.
|
|
4117
4148
|
|
|
4118
4149
|
* *endpoint* - The endpoint instance
|
|
4119
4150
|
|
|
4120
|
-
|
|
4151
|
+
##### endpoint_run_filters.grape
|
|
4121
4152
|
|
|
4122
4153
|
* *endpoint* - The endpoint instance
|
|
4123
4154
|
* *filters* - The filters being executed
|
|
4124
4155
|
* *type* - The type of filters (before, before_validation, after_validation, after)
|
|
4125
4156
|
|
|
4126
|
-
|
|
4157
|
+
##### endpoint_run_validators.grape
|
|
4127
4158
|
|
|
4128
4159
|
The execution of validators.
|
|
4129
4160
|
|
|
@@ -4131,7 +4162,7 @@ The execution of validators.
|
|
|
4131
4162
|
* *validators* - The validators being executed
|
|
4132
4163
|
* *request* - The request being validated
|
|
4133
4164
|
|
|
4134
|
-
|
|
4165
|
+
##### format_response.grape
|
|
4135
4166
|
|
|
4136
4167
|
Serialization or template rendering.
|
|
4137
4168
|
|
|
@@ -4140,12 +4171,44 @@ Serialization or template rendering.
|
|
|
4140
4171
|
|
|
4141
4172
|
See the [ActiveSupport::Notifications documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) for information on how to subscribe to these events.
|
|
4142
4173
|
|
|
4174
|
+
#### Subscribe to Hooks
|
|
4175
|
+
|
|
4176
|
+
Once subscribed to the instrumentation, you can intercept the events reported above.
|
|
4177
|
+
|
|
4178
|
+
```ruby
|
|
4179
|
+
ActiveSupport::Notifications.subscribe(/<api_path>/) do |name, start, finish, id, payload|
|
|
4180
|
+
# your code to intercept the notification
|
|
4181
|
+
end
|
|
4182
|
+
```
|
|
4183
|
+
|
|
4184
|
+
The request data, the API’s internal data, and the response can be retrieved from the payload.
|
|
4185
|
+
|
|
4186
|
+
You can use `payload.fetch(:endpoint)` or directly `payload[:endpoint]`.
|
|
4187
|
+
|
|
4188
|
+
The `:endpoint` contains the data currently being processed, and access to attributes such as `body`, `request`, `params`, `headers`, `cookies` and `response_cookies`
|
|
4189
|
+
|
|
4190
|
+
For example, `payload[:endpoint].body` provides the current state of the response.
|
|
4191
|
+
|
|
4192
|
+
```ruby
|
|
4193
|
+
ActiveSupport::Notifications.subscribe(/v1/) do |name, start, finish, id, payload|
|
|
4194
|
+
hook_record = {
|
|
4195
|
+
hook: name
|
|
4196
|
+
status: payload[:env]&.dig("api.endpoint")&.status
|
|
4197
|
+
format: payload[:env]&.dig("api.format")
|
|
4198
|
+
body: payload[:endpoint]&.body
|
|
4199
|
+
duration: (finish - start) * 1000
|
|
4200
|
+
}
|
|
4201
|
+
# your code to save the notification
|
|
4202
|
+
end
|
|
4203
|
+
```
|
|
4204
|
+
|
|
4143
4205
|
### Monitoring Products
|
|
4144
4206
|
|
|
4145
4207
|
Grape integrates with following third-party tools:
|
|
4146
4208
|
|
|
4147
4209
|
* **New Relic** - [built-in support](https://docs.newrelic.com/docs/agents/ruby-agent/frameworks/grape-instrumentation) from v3.10.0 of the official [newrelic_rpm](https://github.com/newrelic/rpm) gem, also [newrelic-grape](https://github.com/xinminlabs/newrelic-grape) gem
|
|
4148
4210
|
* **Librato Metrics** - [grape-librato](https://github.com/seanmoon/grape-librato) gem
|
|
4211
|
+
* **Rails Performance** - [rails_performance](https://github.com/igorkasyanchuk/rails_performance) gem
|
|
4149
4212
|
* **[Skylight](https://www.skylight.io/)** - [skylight](https://github.com/skylightio/skylight-ruby) gem, [documentation](https://docs.skylight.io/grape/)
|
|
4150
4213
|
* **[AppSignal](https://www.appsignal.com)** - [appsignal-ruby](https://github.com/appsignal/appsignal-ruby) gem, [documentation](http://docs.appsignal.com/getting-started/supported-frameworks.html#grape)
|
|
4151
4214
|
* **[ElasticAPM](https://www.elastic.co/products/apm)** - [elastic-apm](https://github.com/elastic/apm-agent-ruby) gem, [documentation](https://www.elastic.co/guide/en/apm/agent/ruby/3.x/getting-started-rack.html#getting-started-grape)
|
data/UPGRADING.md
CHANGED
|
@@ -1,6 +1,95 @@
|
|
|
1
1
|
Upgrading Grape
|
|
2
2
|
===============
|
|
3
3
|
|
|
4
|
+
### Upgrading to >= 3.0.0
|
|
5
|
+
|
|
6
|
+
#### Ruby 3+ Argument Delegation Modernization
|
|
7
|
+
|
|
8
|
+
Grape has been modernized to use Ruby 3+'s preferred argument delegation patterns. This change replaces `args.extract_options!` with explicit `**kwargs` parameters throughout the codebase.
|
|
9
|
+
|
|
10
|
+
- All DSL methods now use explicit keyword arguments (`**kwargs`) instead of extracting options from mixed argument lists
|
|
11
|
+
- Method signatures are now more explicit and follow Ruby 3+ best practices
|
|
12
|
+
- The `active_support/core_ext/array/extract_options` dependency has been removed
|
|
13
|
+
|
|
14
|
+
This is a modernization effort that improves code quality while maintaining full backward compatibility.
|
|
15
|
+
|
|
16
|
+
See [#2618](https://github.com/ruby-grape/grape/pull/2618) for more information.
|
|
17
|
+
|
|
18
|
+
#### Configuration API Migration from ActiveSupport::Configurable to Dry::Configurable
|
|
19
|
+
|
|
20
|
+
Grape has migrated from `ActiveSupport::Configurable` to `Dry::Configurable` for its configuration system since its [deprecated](https://github.com/rails/rails/blob/1cdd190a25e483b65f1f25bbd0f13a25d696b461/activesupport/lib/active_support/configurable.rb#L3-L7).
|
|
21
|
+
|
|
22
|
+
See [#2617](https://github.com/ruby-grape/grape/pull/2617) for more information.
|
|
23
|
+
|
|
24
|
+
#### Endpoint execution simplified and `return` deprecated
|
|
25
|
+
|
|
26
|
+
Executing a endpoint's block has been simplified and calling `return` in it has been deprecated. Use `next` instead.
|
|
27
|
+
|
|
28
|
+
See [#2577](https://github.com/ruby-grape/grape/pull/2577) for more information.
|
|
29
|
+
|
|
30
|
+
#### Old Deprecations Clean Up
|
|
31
|
+
|
|
32
|
+
- `rack_response` has been removed in favor of using `error!`.
|
|
33
|
+
- `Grape::Exceptions::MissingGroupType` and `Grape::Exceptions::UnsupportedGroupType` aliases `MissingGroupTypeError and `UnsupportedGroupType` have been removed.
|
|
34
|
+
- `Grape::Validations::Base` has been removed in favor of `Grape::Validations::Validators::Base`.
|
|
35
|
+
|
|
36
|
+
See [2573](https://github.com/ruby-grape/grape/pull/2573) for more information.
|
|
37
|
+
|
|
38
|
+
### Upgrading to >= 2.4.0
|
|
39
|
+
|
|
40
|
+
#### Grape::Middleware::Auth::Base
|
|
41
|
+
`type` is now validated at compile time and will raise a `Grape::Exceptions::UnknownAuthStrategy` if unknown.
|
|
42
|
+
|
|
43
|
+
#### Grape::Middleware::Base
|
|
44
|
+
|
|
45
|
+
- Second argument `options` is now a double splat (**) instead of single splat (*). If you're redefining `initialize` in your middleware and/or calling `super` in it, you might have to adapt the signature and the `super` call. Also, you might have to remove `{}` if you're pass `options` as a literal `Hash` or add `**` if you're using a variable.
|
|
46
|
+
- `Grape::Middleware::Helpers` has been removed. The equivalent method `context` is now part of `Grape::Middleware::Base`.
|
|
47
|
+
|
|
48
|
+
#### Grape::Http::Headers, Grape::Util::Lazy::Object
|
|
49
|
+
|
|
50
|
+
Both have been removed. See [2554](https://github.com/ruby-grape/grape/pull/2554).
|
|
51
|
+
Here are the notable changes:
|
|
52
|
+
|
|
53
|
+
- Constants like `HTTP_ACCEPT` have been replaced by their literal value.
|
|
54
|
+
- `SUPPORTED_METHODS` has been moved to `Grape` module.
|
|
55
|
+
- `HTTP_HEADERS` has been moved to `Grape::Request` and renamed `KNOWN_HEADERS`. The last has been refreshed with new headers, and it's not lazy anymore.
|
|
56
|
+
- `SUPPORTED_METHODS_WITHOUT_OPTIONS` and `find_supported_method` have been removed.
|
|
57
|
+
|
|
58
|
+
#### Grape::Middleware::Base
|
|
59
|
+
|
|
60
|
+
- Constant `TEXT_HTML` has been removed in favor of using literal string 'text/html'.
|
|
61
|
+
- `rack_request` and `query_params` have been added. Feel free to call these in your middlewares.
|
|
62
|
+
|
|
63
|
+
#### Params Builder
|
|
64
|
+
|
|
65
|
+
- Passing a class to `build_with` or `Grape.config.param_builder` has been deprecated in favor of a symbolized short_name. See `SHORTNAME_LOOKUP` in [params_builder](lib/grape/params_builder.rb).
|
|
66
|
+
- Including Grape's extensions like `Grape::Extensions::Hashie::Mash::ParamBuilder` has been deprecated in favor of using `build_with` at the route level.
|
|
67
|
+
|
|
68
|
+
#### Accept Header Negotiation Harmonized
|
|
69
|
+
|
|
70
|
+
[Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept) header is now fully interpreted through `Rack::Utils.best_q_match` which is following [RFC2616 14.1](https://datatracker.ietf.org/doc/html/rfc2616#section-14.1). Since [Grape 2.1.0](https://github.com/ruby-grape/grape/blob/master/CHANGELOG.md#210-20240615), the [header versioning strategy](https://github.com/ruby-grape/grape?tab=readme-ov-file#header) was adhering to it, but `Grape::Middleware::Formatter` never did.
|
|
71
|
+
|
|
72
|
+
Your API might act differently since it will strictly follow the [RFC2616 14.1](https://datatracker.ietf.org/doc/html/rfc2616#section-14.1) when interpreting the `Accept` header. Here are the differences:
|
|
73
|
+
|
|
74
|
+
##### Invalid or missing quality ranking
|
|
75
|
+
The following used to yield `application/xml` and now will yield `application/json` as the preferred media type:
|
|
76
|
+
- `application/json;q=invalid,application/xml;q=0.5`
|
|
77
|
+
- `application/json,application/xml;q=1.0`
|
|
78
|
+
|
|
79
|
+
For the invalid case, the value `invalid` was automatically `to_f` and `invalid.to_f` equals `0.0`. Now, since it doesn't match [Rack's regex](https://github.com/rack/rack/blob/3-1-stable/lib/rack/utils.rb#L138), its interpreted as non provided and its quality ranking equals 1.0.
|
|
80
|
+
|
|
81
|
+
For the non provided case, 1.0 was automatically assigned and in a case of multiple best matches, the first was returned based on Ruby's sort_by `quality`. Now, 1.0 is still assigned and the last is returned in case of multiple best matches. See [Rack's implementation](https://github.com/rack/rack/blob/e8f47608668d507e0f231a932fa37c9ca551c0a5/lib/rack/utils.rb#L167) of the RFC.
|
|
82
|
+
|
|
83
|
+
##### Considering the closest generic when vendor tree
|
|
84
|
+
Excluding the [header versioning strategy](https://github.com/ruby-grape/grape?tab=readme-ov-file#header), whenever a media type with the [vendor tree](https://datatracker.ietf.org/doc/html/rfc6838#section-3.2) leading facet `vnd.` like `application/vnd.api+json` was provided, Grape would also consider its closest generic when negotiating. In that case, `application/json` was added to the negotiation. Now, it will just consider the provided media types without considering any closest generics, and you'll need to [register](https://github.com/ruby-grape/grape?tab=readme-ov-file#api-formats) it.
|
|
85
|
+
You can find the official vendor tree registrations on [IANA](https://www.iana.org/assignments/media-types/media-types.xhtml)
|
|
86
|
+
|
|
87
|
+
#### Custom Validators
|
|
88
|
+
|
|
89
|
+
If you now receive an error of `'Grape::Validations.require_validator': unknown validator: your_custom_validation (Grape::Exceptions::UnknownValidator)` after upgrading to 2.4.0 then you will need to ensure that you require the `your_custom_validation` file before your Grape API code is loaded.
|
|
90
|
+
|
|
91
|
+
See [2533](https://github.com/ruby-grape/grape/issues/2533) for more information.
|
|
92
|
+
|
|
4
93
|
### Upgrading to >= 2.3.0
|
|
5
94
|
|
|
6
95
|
### `content_type` vs `api.format` inside API
|
|
@@ -83,7 +172,7 @@ When using together with `Grape::Extensions::Hash::ParamBuilder`, `route_param`
|
|
|
83
172
|
This was a regression introduced by [#2326](https://github.com/ruby-grape/grape/pull/2326) in Grape v1.8.0.
|
|
84
173
|
|
|
85
174
|
```ruby
|
|
86
|
-
|
|
175
|
+
Grape.configure do |config|
|
|
87
176
|
config.param_builder = Grape::Extensions::Hash::ParamBuilder
|
|
88
177
|
end
|
|
89
178
|
|
data/grape.gemspec
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
require 'grape/version'
|
|
3
|
+
require_relative 'lib/grape/version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |s|
|
|
7
6
|
s.name = 'grape'
|
|
@@ -21,7 +20,8 @@ Gem::Specification.new do |s|
|
|
|
21
20
|
'rubygems_mfa_required' => 'true'
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
s.add_dependency 'activesupport', '>=
|
|
23
|
+
s.add_dependency 'activesupport', '>= 7.0'
|
|
24
|
+
s.add_dependency 'dry-configurable'
|
|
25
25
|
s.add_dependency 'dry-types', '>= 1.1'
|
|
26
26
|
s.add_dependency 'mustermann-grape', '~> 1.1.0'
|
|
27
27
|
s.add_dependency 'rack', '>= 2'
|
|
@@ -29,5 +29,5 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
|
|
30
30
|
s.files = Dir['lib/**/*', 'CHANGELOG.md', 'CONTRIBUTING.md', 'README.md', 'grape.png', 'UPGRADING.md', 'LICENSE', 'grape.gemspec']
|
|
31
31
|
s.require_paths = ['lib']
|
|
32
|
-
s.required_ruby_version = '>=
|
|
32
|
+
s.required_ruby_version = '>= 3.0'
|
|
33
33
|
end
|