You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 26906e7
Browse filesBrowse the repository at this point in the historyBrowse files
Answer a route opening with an optional segment without it under a namespace
A route's path is assembled by joining its mount path, prefix, version,
namespace and own path with slashes. A path opening with an optional
group, such as get '(:type)' inside namespace :root, compiled to
/root/(:type): the slash outside the group was required, and a request
path is normalized without a trailing slash, so /root answered 404. The
same went for a mount path, a prefix, a path version, and a slash
written in front of the group, as in get 'users/(:id)'.
The slash in front of an optional group now goes inside it, as
/root(/:type), the spelling that already worked when written out in
full. A slash opening the path stays where it is, so / still matches
/(:type).
Fixes#932.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,6 +19,7 @@
19
19
*[#3055](https://github.com/ruby-grape/grape/pull/3055): Stop a 405 behind `Rack::Cascade` from making the next app answer 405 too - [@ericproulx](https://github.com/ericproulx).
20
20
*[#3058](https://github.com/ruby-grape/grape/pull/3058): Declare `rexml` in the test bundle instead of relying on Danger to bring it in - [@ericproulx](https://github.com/ericproulx).
21
21
*[#3064](https://github.com/ruby-grape/grape/pull/3064): Cascade past a mounted Rack app that declines with a lowercase `x-cascade` - [@ericproulx](https://github.com/ericproulx).
22
+
*[#XXXX](https://github.com/ruby-grape/grape/pull/XXXX): Answer a route opening with an optional segment without it under a namespace, prefix or mount path - [@ericproulx](https://github.com/ericproulx).
Copy file name to clipboardExpand all lines: UPGRADING.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,13 @@ Upgrading Grape
3
3
4
4
### Upgrading to >= 4.2.0
5
5
6
+
#### A path opening with an optional segment answers without it under a namespace
7
+
8
+
A route path opening with an optional segment, such as `get '(:type)'` inside `namespace :root`, now also answers `/root` ([#XXXX](https://github.com/ruby-grape/grape/pull/XXXX)). Before, the slash Grape put between the namespace and the path was required, and a request path is never matched with a trailing slash, so `/root` answered `404`. The same goes for a mount path, a prefix, a path version, and a slash written in front of the segment, as in `get 'users/(:id)'`.
9
+
10
+
* The route's `path` and `origin` move the slash into the segment: `/root(/:type)` instead of `/root/(:type)`. Anything reading them, such as API documentation, sees the new spelling.
11
+
* A route declared after it for the path itself, such as `get` in the same namespace, no longer answers that path, as the earlier route now matches it first. Declare that route first, or drop it.
12
+
6
13
#### A request every route declines answers 404, however many routes declined
7
14
8
15
A route declines a request by answering with `X-Cascade: pass`, as a version declared with `cascade: true` does for a version it does not serve. As the [README](README.md#header) documents, the router then answers its own `404` if no other route takes the request. It only did so when one route had declined: with two or more routes on the path, the last one's response came back instead, and so did that of an ANY route (since 4.0.0). So a request for an unknown version answered `404` from an API with one version and `406` from an API with several.
0 commit comments