Skip to content

fallback in nested router isn't used when other routes on the root router match #3138

@syphar

Description

@syphar
  • I have looked for existing issues (including closed) about this

Bug Report

Version

├── axum v0.8.1
│   ├── axum-core v0.5.0

Platform

Darwin mondo-0984 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000 arm64

Description

When trying to migrate docs.rs to axum 0.8 I stumbled onto an issue with nested routing and fallbacks. In the breaking changes from the changelog I didn't see anything obvious that I did wrong, and the documentation still states the behaviour that I expect.

I have this example code:

use axum::{
    http::{StatusCode, Uri},
    routing::get,
    Json, Router,
};

async fn fallback() -> (StatusCode, &'static str) {
    (StatusCode::NOT_FOUND, "Not Found Root")
}

async fn api_fallback() -> (StatusCode, Json<serde_json::Value>) {
    (
        StatusCode::NOT_FOUND,
        Json(serde_json::json!({ "status": "Not Found API" })),
    )
}

#[tokio::main]
async fn main() {
    let api_routes = Router::new()
        .route("/users", get(|| async {}))
        .fallback(api_fallback);

    let app = Router::new()
        .nest("/api", api_routes)
        .route(
            "/{name}/{version}",
            get(|uri: Uri| async move { uri.to_string() }),
        )
        .fallback(fallback);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

Following the documentation about fallbacks and a nested router I would expect that a request to /api/something would lead to api_fallback being called.

But what happens is that the route behind /{name}/{version} is called.

In our case I have a nested router for static assets behind /-/static and want a custom static fallback if the first static routes don't match.

with axum ~0.7 we used get_service here, which is not allowed any more, which is why I wanted to migrate to fallback_service.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions