seanmonstar / warp

A super-easy, composable, web server framework for warp speeds.
https://seanmonstar.com/post/176530511587/warp
MIT License
9.58k stars 720 forks source link

Allow passing constructed routes to another function (expose IsReject) #901

Open camelop opened 3 years ago

camelop commented 3 years ago

Is your feature request related to a problem? Please describe. In our application, we construct different routes and start TLS server in different places, the resulting code looks like:

async fn foo_1(...) {
    let routes = .....
    warp::serve(routes)
      .tls()
      .key_path("...")
      .cert_path("...")
      .client_auth_required_path("...")
      .run(([0, 0, 0, 0], port))
      .await;
}

async fn foo_2(...) {
    let routes = ..... // something different
    warp::serve(routes)
      .tls()
      .key_path("...")
      .cert_path("...")
      .client_auth_required_path("...")
      .run(([0, 0, 0, 0], port))
      .await;
}

However, we want to simplify the code by constructing a separate function that looks like:

async fn warp_serve<F>(routes: F)
    where
        F: Filter + Clone + Send + Sync + 'static,
        F::Extract: Reply,
        F::Error: IsReject,
    {
    warp::serve(routes)
      .tls()
      .key_path("...")
      .cert_path("...")
      .client_auth_required_path("...")
      .run(([0, 0, 0, 0], port))
      .await;
    }

Then we can simplify the code in the beginning to be

fn foo_1(...) {
    let routes = .....
    warp_serve(routes).await;
}

fn foo_2(...) {
    let routes = ..... // something different
    warp_serve(routes).await;
}

But we cannot do that because "trait IsReject is private" so warp_serve cannot compile.

Describe the solution you'd like A clear and concise description of what you want to happen: Make IsReject a public trait.

Describe alternatives you've considered: N/A

Additional context: N/A

char commented 2 years ago

Managed to work around this [at a slight performance penalty] by returning a BoxedFilter<(warp::reply::Response,)> from the route constructor and doing a {...}.map(Reply::into_response).boxed() :)

camelop commented 2 years ago

Managed to work around this [at a slight performance penalty] by returning a BoxedFilter<(warp::reply::Response,)> from the route constructor and doing a {...}.map(Reply::into_response).boxed() :)

Thanks a lot for providing the solution and happy new year!

While in our internal project development we are doing some similar workarounds, the change of just making the trait public might be more direct and does not harm the purpose of defensive programming. I would probably send a PR myself on this later and hopefully, the dev team can also help with this.

chpio commented 2 years ago

Fix for this problem? https://github.com/seanmonstar/warp/issues/944

qm3ster commented 1 year ago

@chpio they are seeking to accept routes while I am seeking to return routes, but indeed making a public Route(s?) abstraction fixes both without/instead of making IsReject public. I could PR, but it's unclear to me which is the better long term evolution public surface area change.