Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Custom layers on *nested* router isn't getting called #1245

Closed
bryanburgers opened this issue Aug 10, 2022 · 1 comment
Closed

Custom layers on *nested* router isn't getting called #1245

bryanburgers opened this issue Aug 10, 2022 · 1 comment

Comments

@bryanburgers
Copy link
Contributor

Bug Report

I created a service to do some custom routing that isn't supported by axum::Router. When I add it to a root-level router, it works fine. However, when I add it to a router and then nest that router, it doesn't ever seem to be called.

// This seems to work
let my_custom_router = ...;
let app = Router::new().layer(my_custom_router);
// This compiles, but my custom router never gets calls to `Service::call`
let my_custom_router = ...;
let nested = Router::new().layer(my_custom_router);
let app = Router::new().nest("/nested", nested);

Version

axum-nest-repro v0.1.0 (/Users/bryan/personal/axum-nest-repro)
├── axum v0.5.15
│   ├── axum-core v0.2.7

Platform

Darwin Bryans-MacBook-Pro.local 20.6.0 Darwin Kernel Version 20.6.0: Tue Feb 22 21:10:41 PST 2022; root:xnu-7195.141.26~1/RELEASE_X86_64 x86_64

Crates

  • axum

Description

As mentioned above, it seems like when calling Router::nest with another Router as the target, my custom layer gets lost.

However, if I turn my custom layer into a service without using another Router and nest that, it seems to work fine (but then I lose the ability to do other additional routing).

Summary:

  • 🥰 Custom layer at root level
  • 🥰 Custom layer when turned into its own service and nested
  • 🤬 Custom layer added to another Router, then nested in root Router

Reproduction is here: https://github.com/bryanburgers/axum-nest-repro.

To try it out, you can do cargo run in one terminal to start the server on 0.0.0.0:3000 and cargo test in another terminal.

Ultimately, the code that I would like to work looks like this

pub fn create_app(context: Context) -> Router {
    let odata_layer = odata_router::Router::new()
        .get("Property", get_property)    // GET /odata/Property('12345')
        .list("Property", list_property); // GET /odata/Property?$query=... 
    let odata_router = Router::new().layer(odata_layer);

    let api_router = Router::new()
        .route("/properties", get(list_own_properties).post(post_new_property))
        .route("/properties/:id", get(get_own_property).patch(patch_own_property))
        .route("/properties/:id/validate", post(validate_own_property));

    Router::new()
        .nest("/api", api_router)
        .nest("/odata", odata_router)
        .layer(Extension(context))

but once I try to nest odata_router instead of putting .layer(odata_layer) on the root, I can no longer get the odata_layer to handle requests.

@davidpdrsn
Copy link
Member

Router::new().layer(odata_layer); only adds the layer to the fallback which is then discarded when you nest the router. Axum 0.5 doesn't support nested fallbacks.

A workaround is to box the nested service Router::new().layer(odata_layer).boxed_clone() using ServiceExt::boxed_clone.

@tokio-rs tokio-rs locked and limited conversation to collaborators Aug 11, 2022
@davidpdrsn davidpdrsn converted this issue into discussion #1246 Aug 11, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants