Skip to content

Commit 4a89c18

Browse files
committed
Merge branch 'master' into less_active_support_concern
2 parents 73f7bbd + 3a06a60 commit 4a89c18

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+838
-587
lines changed

.github/workflows/edge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
bundler-cache: true
2828

2929
- name: Run tests
30-
run: bundle exec rake spec
30+
run: "RUBYOPT='--enable=frozen-string-literal' bundle exec rspec"
3131

3232
- name: Coveralls
3333
uses: coverallsapp/github-action@v2

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
bundler-cache: true
8585

8686
- name: Run Tests (${{ matrix.specs }})
87-
run: bundle exec rspec ${{ matrix.specs }}
87+
run: "RUBYOPT='--enable=frozen-string-literal' bundle exec rspec ${{ matrix.specs }}"
8888

8989
- name: Coveralls
9090
uses: coverallsapp/github-action@v2

.rubocop.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ AllCops:
77
- bin/**/*
88

99
require:
10-
- rubocop-performance
1110
- rubocop-rspec
1211

12+
plugins:
13+
- rubocop-performance
14+
1315
inherit_from: .rubocop_todo.yml
1416

1517
Layout/LineLength:

CHANGELOG.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
1-
### 2.4.0 (Next)
1+
### 3.0.0 (Next)
2+
3+
#### Features
4+
5+
* [#2574](https://github.com/ruby-grape/grape/pull/2574): Reduce `ActiveSupport::Concern` usage - [@ericproulx](https://github.com/ericproulx).
6+
* Your contribution here.
7+
8+
#### Fixes
9+
10+
* Your contribution here.
11+
12+
### 2.4.0 (2025-06-18)
213

314
#### Features
415

516
* [#2532](https://github.com/ruby-grape/grape/pull/2532): Update RuboCop 1.71.2 - [@ericproulx](https://github.com/ericproulx).
6-
* [#2535](https://github.com/ruby-grape/grape/pull/2535): Delegates calls to inner objects - [@ericproulx](https://github.com/ericproulx).
17+
* [#2535](https://github.com/ruby-grape/grape/pull/2535): Delegate calls to inner objects - [@ericproulx](https://github.com/ericproulx).
718
* [#2537](https://github.com/ruby-grape/grape/pull/2537): Use activesupport `try` pattern - [@ericproulx](https://github.com/ericproulx).
819
* [#2536](https://github.com/ruby-grape/grape/pull/2536): Update normalize_path like Rails - [@ericproulx](https://github.com/ericproulx).
9-
* [#2540](https://github.com/ruby-grape/grape/pull/2540): Introduce Params builder with symbolized short name - [@ericproulx](https://github.com/ericproulx).
20+
* [#2540](https://github.com/ruby-grape/grape/pull/2540): Introduce params builder with symbolized short name - [@ericproulx](https://github.com/ericproulx).
1021
* [#2550](https://github.com/ruby-grape/grape/pull/2550): Drop ActiveSupport 6.0 - [@ericproulx](https://github.com/ericproulx).
1122
* [#2549](https://github.com/ruby-grape/grape/pull/2549): Delegate cookies management to `Grape::Request` - [@ericproulx](https://github.com/ericproulx).
12-
* Your contribution here.
23+
* [#2554](https://github.com/ruby-grape/grape/pull/2554): Remove `Grape::Http::Headers` and `Grape::Util::Lazy::Object` - [@ericproulx](https://github.com/ericproulx).
24+
* [#2556](https://github.com/ruby-grape/grape/pull/2556): Remove unused `Grape::Request::DEFAULT_PARAMS_BUILDER` constant - [@eriklovmo](https://github.com/eriklovmo).
25+
* [#2558](https://github.com/ruby-grape/grape/pull/2558): Add Ruby's option `enable_frozen_string_literal` in CI - [@ericproulx](https://github.com/ericproulx).
26+
* [#2557](https://github.com/ruby-grape/grape/pull/2557): Add `lint!` - [@ericproulx](https://github.com/ericproulx).
27+
* [#2561](https://github.com/ruby-grape/grape/pull/2561): Optimize hash alloc for middleware's default options - [@ericproulx](https://github.com/ericproulx).
28+
* [#2563](https://github.com/ruby-grape/grape/pull/2563): Update `Grape::Middleware::Auth::Base` - [@ericproulx](https://github.com/ericproulx).
29+
* [#2571](https://github.com/ruby-grape/grape/pull/2571): Update RuboCop 1.75.8 - [@pieterocp](https://github.com/pieterocp).
1330

1431
#### Fixes
1532

1633
* [#2538](https://github.com/ruby-grape/grape/pull/2538): Fix validating nested json array params - [@mohammednasser-32](https://github.com/mohammednasser-32).
1734
* [#2543](https://github.com/ruby-grape/grape/pull/2543): Fix array allocation on mount - [@ericproulx](https://github.com/ericproulx).
1835
* [#2546](https://github.com/ruby-grape/grape/pull/2546): Fix middleware with keywords - [@ericproulx](https://github.com/ericproulx).
1936
* [#2547](https://github.com/ruby-grape/grape/pull/2547): Remove jsonapi related code - [@ericproulx](https://github.com/ericproulx).
20-
* Your contribution here.
37+
* [#2548](https://github.com/ruby-grape/grape/pull/2548): Formatting from header acts like versioning from header - [@ericproulx](https://github.com/ericproulx).
38+
* [#2552](https://github.com/ruby-grape/grape/pull/2552): Fix declared params optional array - [@ericproulx](https://github.com/ericproulx).
39+
* [#2553](https://github.com/ruby-grape/grape/pull/2553): Improve performance of query params parsing - [@ericproulx](https://github.com/ericproulx).
2140

2241
### 2.3.0 (2025-02-08)
2342

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ group :development, :test do
1010
gem 'builder', require: false
1111
gem 'bundler'
1212
gem 'rake'
13-
gem 'rubocop', '1.71.2', require: false
14-
gem 'rubocop-performance', '1.23.1', require: false
13+
gem 'rubocop', '1.75.8', require: false
14+
gem 'rubocop-performance', '1.25.0', require: false
1515
gem 'rubocop-rspec', '3.4.0', require: false
1616
end
1717

README.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
- [Header](#header)
2929
- [Accept-Version Header](#accept-version-header)
3030
- [Param](#param)
31+
- [Linting](#linting)
32+
- [Bug in Rack::ETag under Rack 3.X](#bug-in-racketag-under-rack-3x)
3133
- [Describing Methods](#describing-methods)
3234
- [Configuration](#configuration)
3335
- [Parameters](#parameters)
@@ -154,8 +156,8 @@ Grape is a REST-like API framework for Ruby. It's designed to run on Rack or com
154156

155157
## Stable Release
156158

157-
You're reading the documentation for the next release of Grape, which should be 2.4.0.
158-
The current stable release is [2.3.0](https://github.com/ruby-grape/grape/blob/v2.3.0/README.md).
159+
You're reading the documentation for the next release of Grape, which should be 3.0.0.
160+
The current stable release is [2.4.0](https://github.com/ruby-grape/grape/blob/v2.4.0/README.md).
159161

160162
## Project Resources
161163

@@ -269,7 +271,7 @@ Grape's [deprecator](https://api.rubyonrails.org/v7.1.0/classes/ActiveSupport/De
269271
### All
270272

271273

272-
By default Grape will compile the routes on the first route, it is possible to pre-load routes using the `compile!` method.
274+
By default Grape will compile the routes on the first route, but it is possible to pre-load routes using the `compile!` method.
273275

274276
```ruby
275277
Twitter::API.compile!
@@ -650,6 +652,27 @@ version 'v1', using: :param, parameter: 'v'
650652
curl http://localhost:9292/statuses/public_timeline?v=v1
651653

652654

655+
## Linting
656+
657+
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).
658+
659+
```ruby
660+
class Api < Grape::API
661+
lint!
662+
end
663+
```
664+
```ruby
665+
Grape.configure do |config|
666+
config.lint = true
667+
end
668+
```
669+
```ruby
670+
Grape.config.lint = true
671+
```
672+
673+
### Bug in Rack::ETag under Rack 3.X
674+
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.
675+
653676
## Describing Methods
654677

655678
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.

UPGRADING.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
Upgrading Grape
22
===============
33

4+
### Upgrading to >= 2.4.0
5+
6+
#### Grape::Middleware::Auth::Base
7+
`type` is now validated at compile time and will raise a `Grape::Exceptions::UnknownAuthStrategy` if unknown.
8+
9+
#### Grape::Middleware::Base
10+
11+
- 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.
12+
- `Grape::Middleware::Helpers` has been removed. The equivalent method `context` is now part of `Grape::Middleware::Base`.
13+
14+
#### Grape::Http::Headers, Grape::Util::Lazy::Object
15+
16+
Both have been removed. See [2554](https://github.com/ruby-grape/grape/pull/2554).
17+
Here are the notable changes:
18+
19+
- Constants like `HTTP_ACCEPT` have been replaced by their literal value.
20+
- `SUPPORTED_METHODS` has been moved to `Grape` module.
21+
- `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.
22+
- `SUPPORTED_METHODS_WITHOUT_OPTIONS` and `find_supported_method` have been removed.
23+
24+
#### Grape::Middleware::Base
25+
26+
- Constant `TEXT_HTML` has been removed in favor of using literal string 'text/html'.
27+
- `rack_request` and `query_params` have been added. Feel free to call these in your middlewares.
28+
429
#### Params Builder
530

631
- 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).
732
- Including Grape's extensions like `Grape::Extensions::Hashie::Mash::ParamBuilder` has been deprecated in favor of using `build_with` at the route level.
833

9-
### Upgrading to >= 2.4.0
34+
#### Accept Header Negotiation Harmonized
35+
36+
[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.
37+
38+
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:
39+
40+
##### Invalid or missing quality ranking
41+
The following used to yield `application/xml` and now will yield `application/json` as the preferred media type:
42+
- `application/json;q=invalid,application/xml;q=0.5`
43+
- `application/json,application/xml;q=1.0`
44+
45+
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.
46+
47+
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.
48+
49+
##### Considering the closest generic when vendor tree
50+
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.
51+
You can find the official vendor tree registrations on [IANA](https://www.iana.org/assignments/media-types/media-types.xhtml)
1052

1153
#### Custom Validators
1254

@@ -96,7 +138,7 @@ When using together with `Grape::Extensions::Hash::ParamBuilder`, `route_param`
96138
This was a regression introduced by [#2326](https://github.com/ruby-grape/grape/pull/2326) in Grape v1.8.0.
97139

98140
```ruby
99-
grape.configure do |config|
141+
Grape.configure do |config|
100142
config.param_builder = Grape::Extensions::Hash::ParamBuilder
101143
end
102144

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
volumes:
42
gems:
53

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ENV RUBYOPT --enable-frozen-string-literal --yjit
77
ENV LD_PRELOAD libjemalloc.so.2
88
ENV MALLOC_CONF dirty_decay_ms:1000,narenas:2,background_thread:true
99

10-
RUN apk add --update --no-cache make gcc git libc-dev gcompat jemalloc && \
10+
RUN apk add --update --no-cache make gcc git libc-dev yaml-dev gcompat jemalloc && \
1111
gem update --system && gem install bundler
1212

1313
WORKDIR $LIB_PATH

lib/grape.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,23 @@
5959
module Grape
6060
include ActiveSupport::Configurable
6161

62+
HTTP_SUPPORTED_METHODS = [
63+
Rack::GET,
64+
Rack::POST,
65+
Rack::PUT,
66+
Rack::PATCH,
67+
Rack::DELETE,
68+
Rack::HEAD,
69+
Rack::OPTIONS
70+
].freeze
71+
6272
def self.deprecator
6373
@deprecator ||= ActiveSupport::Deprecation.new('2.0', 'Grape')
6474
end
6575

6676
configure do |config|
6777
config.param_builder = :hash_with_indifferent_access
78+
config.lint = false
6879
config.compile_methods!
6980
end
7081
end

0 commit comments

Comments
 (0)