Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default service not defaulting to the parent scope #3217

Open
nokacper24 opened this issue Dec 5, 2023 · 0 comments
Open

default service not defaulting to the parent scope #3217

nokacper24 opened this issue Dec 5, 2023 · 0 comments

Comments

@nokacper24
Copy link

Expected Behavior

When navigating to nonexistent route in a scope, I'd expect to get the nearest default route that is defined.

Current Behavior

Currently, when a scope does not have a default service set up, it will serve the default service set up in the app (or empty 404 if not set up).

Possible Solution

Look for closest definition of default service while "climbing" down the scopes.

Steps to Reproduce

If we setup routes like so:

/ - our root
~default service
/app scope:
    / - root of app scope
    ~default  service for app scope
    /deep scope:
        / - root of deep scope
        ~no default service

If we navigate to /app/something, we'll end up on the app scope's default service.
However, if we go to /app/deep/something, we end up on the topmost default service. (I'd expect to end up on the app scope's default service).

Code

use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(root)
            .service(web::scope("/app").configure(app_config))
            .default_service(web::route().to(default_not_found))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

fn app_config(cfg: &mut web::ServiceConfig) {
    cfg.service(app_hello);
    cfg.service(web::scope("/deep").configure(deep_config));
    cfg.default_service(web::route().to(app_not_found));
}

fn deep_config(cfg: &mut web::ServiceConfig) {
    cfg.service(deep_hello);
}

#[get("/")]
async fn root() -> impl Responder {
    HttpResponse::Ok().body("Root /")
}

async fn default_not_found() -> impl Responder {
    HttpResponse::NotFound().body("Default 404!")
}

#[get("/")]
async fn app_hello() -> impl Responder {
    HttpResponse::Ok().body("this is app/")
}

async fn app_not_found() -> impl Responder {
    HttpResponse::NotFound().body("App scope's 404!")
}

#[get("/")]
async fn deep_hello() -> impl Responder {
    HttpResponse::Ok().body("this is app/deep/")
}

Context

I encountered this behavior when working on a web shop project, where route something like: /products/something/details-scope/nonexistent, I'd end up with the default response from the server, which had nothing to do with the products...

If this is entirely intended, please just correct me. Otherwise, maybe it would be possible to configure the behavior of the default service resolution in scopes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant