Skip to content

Middleware that change the request body have poor usability #1110

@davidpdrsn

Description

@davidpdrsn

We've heard from several people who try to use tower_http::limit::RequestBodyLimitLayer that the implications are hard to understand.

For example breaking your Router into functions is quite common. Something like:

#[tokio::main]
async fn main() {
    let app = my_routes();

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

fn my_routes() -> Router {
    Router::new()
}

Adding RequestBodyLimitLayer like so

let app = my_routes().layer(RequestBodyLimitLayer::new(1024));

should just work but produces a rather confusing error:

    Checking example-hello-world v0.1.0 (/Users/davidpdrsn/dev/major/axum/examples/hello-world)
error[E0277]: the trait bound `Route: tower_service::Service<Request<http_body::limited::Limited<_>>>` is not satisfied
  --> hello-world/src/main.rs:13:27
   |
13 |     let app = my_routes().layer(RequestBodyLimitLayer::new(1024));
   |                           ^^^^^ the trait `tower_service::Service<Request<http_body::limited::Limited<_>>>` is not implemented for `Route`
   |
   = help: the following implementations were found:
             <Route<B, E> as tower_service::Service<Request<B>>>
   = note: required because of the requirements on the impl of `tower_service::Service<Request<_>>` for `RequestBodyLimit<Route>`

The solution is instead to write

fn my_routes() -> Router<http_body::Limited<Body>> {
    Router::new()
}

but that isn't obvious and ideally shouldn't be necessary.

We should think about ways to improve that experience.

Metadata

Metadata

Assignees

Labels

A-axumC-musingsCategory: musings about a better worldE-hardCall for participation: Experience needed to fix: Hard / a lot

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions