Scope only serve the first sub-scope
- Langage dominant
- Rust
- Étoiles
- 24.8k
- Forks
- 1.9k
- Merge moyen
- 23 h 10 min
- PR mergées (30 j)
- 26
Description
Let's consider the following setup:
```rust
// module base
#[get("/ping")]
pub async fn ping() -> impl Responder {
HttpResponse::Ok().body("ping - ok")
}
pub fn base_router() -> Scope {
web::scope("/")
.service(ping)
.service(b::router())
.service(c::router())
}
[snip]
// create the application using
let app = App::new().service(base_router())
```
```rust
// module b
#[get("/testb")]
async fn test() -> HttpResponse {
HttpResponse::Ok().body("b - test")
}
pub fn router() -> Scope {
web::scope("/")
.service(test)
}
```
```rust
// module c
#[get("/testc")]
async fn test() -> HttpResponse {
HttpResponse::Ok().body("c - test")
}
pub fn router() -> Scope {
web::scope("/")
.service(test)
}
```
```rust
// module d
#[get("/testd")]
async fn test() -> HttpResponse {
HttpResponse::Ok().body("d - test")
}
pub fn router() -> Scope {
web::scope("/smth/")
.service(test)
}
```
## Expected Behavior
The routes `/ping`, `/testb`, and `testc` are all valid and served by the application.
## Current Behavior
The `/ping` route is served (all the services defined directly in the top-level scope in general).
The `/testb` route is served, but not the `/testc` one; only the first sub-scope is served: if we inverse the order of definition (see bellow), then the `/testc` route is served but not the `/testb`
This behaviour is only present if the two sub-scope have the same path or if one of the subscope is set to the "root path" (`/`) and is defined first :
```rust
web::scope("/")
.service(ping) // served
.service(b::router()) // served (root)
.service(c::router()) // not served (root)
web::scope("/")
.service(ping) // served
.service(c::router()) // served (root)
.service(b::router()) // not served (root)
web::scope("/")
.service(ping) // served
.service(d::router()) // served (/smth/)
.service(c::router()) // served (root)
web::scope("/")
.service(ping) // served
.service(c::router()) // served
.service(d::router()) // not served (/smth/)
```
## Context
The only solution I found was not to use any "root" sub-scope. Though I haven't found anything in the documentation preventing me from using the root path in a sub-scope (and the application compiles & run fine).
## Your Environment
Rust 1.53 `rustc 1.53.0 (53cb7b09b 2021-06-17)`
Actix-Web 3 & 4.0.0-beta.8
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Start by reproducing the nested web::scope setup from the issue with App::new().service(), checking the /ping, /testb, /testc, and /testd routes in different registration orders. Trace the scope and service routing entry points to find why only the first same-path sub-scope is served. Done means all expected routes work regardless of sub-scope order, with regression coverage for the shown root and /smth/ combinations.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- rust
- Domaine
- api, backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100