I just read your blog post that introduces the warp library, so I'm quite intrigued now as to how things will develop now with tower and tower-web quickly entering the stage. I am certainly attracted by the design philosophy of warp, but I do want to know how you see it in relation to tower-web, which you mentioned in passing. From an issue you have open here, it would seem the Filter and Service traits are somehow analogous? I'm presuming neither tower-web nor warp will ever include the other as a dependency, but what will the relation between them be, going forwards? Direct competitors?
Side question: does warp support async workflows like Gotham or such?
We've been talking about how to reduce duplicate efforts, and find pieces that can be combined. It's possible the projects (tower-web and warp) merge at some point, exposing both APIs as "flavors". If you know the Scala world at all, here is how I see the projects:
So, similar to how in finch, an Endpoint can be converted into a Service, I think a warp::Filter can be converted into a tower::Service (see #56).
does warp support async workflows like Gotham or such?
Yep, the README and the docs both point out that warp is built on top of hyper and thus supports asynchronous request handling.
Thanks for the clarification. Unfortunately I don't know Scala, so those analogies don't help much... I'm still left unsure of whether one framework is better for certain use cases.
Yep, the README and the docs both point out that warp is built on top of hyper and thus supports asynchronous request handling.
I just looked at the docs closer, and I think I see how you do it now... I wanted to check, because some web frameworks use hyper internally, but don't expose any async stuff really (even if they use it internally?). But I'm glad!
one framework is better for certain use cases.
The goal is that functionality is available in both, and the choice comes down to personal taste of how you prefer structure web apps.
We've been talking about how to reduce duplicate efforts, and find pieces that can be combined. It's possible the projects (tower-web and warp) merge at some point, exposing both APIs as "flavors". If you know the Scala world at all, here is how I see the projects:
The current state of these projects is going to the wrong direction (as I think).
1) https://github.com/carllerche/tower-web/tree/master/src/middleware
2) https://github.com/seanmonstar/warp/pull/73 (Cors)
3) https://github.com/seanmonstar/warp/issues/46 (Content compression)
Both warp and tower-web are starting to develop their web frameworks, which breaks the main finagle rule - "all components just a small functions which implement a simple contract Request -> Futurewarp has Filter abstraction and tower-web has a Middleware abstraction, which are going to duplicate the same functionality.
So both warp and tower-web should implement only routing solution and content negotiation, all other things such as CorsFilter, ServerStatsFilter, RequestLogFilter, etc have to be in tower-http services.
Here an example which that could be (using LiftService)
use tower_http::{Cors, GzipCompression, RequestLog, HttpStats, HttpTracing};
let endpoint = warp::any().map(|| "ok");
let new_service = endpoint.lift()
.and_then(GzipCompression::new)
.and_then(Cors::new)
.and_then(RequestLog::new)
.and_then(HttpStats::new)
.and_then(HttpTracing::new);
server:run(new_service);
@dmexe I agree with the feeling, there are some things that we could be duplicating effort, and we do want to reduce that. I think that providing the ability to plug in any Service with warp is a very useful step. It might make sense for there to be "functional" constructors of these things in warp, that basically just use the Service, I'm unsure. It also may be useful to add functionality in warp before such a Service exists.
At the current time, the "warp" duplicates many things in the tower-web. The most important of them middlewares. Thus the warp's filter abstraction should be revisited.
In the tower-web, the resource uses for matching requests and returning responses. Thus the warp's filter should be another kind of resource, and the warp itself should be "combinators for constructing resources for tower-web" not a yet another web framework.
Required changes at warp:
Required changes at tower-web (later)
At finally it would allow writing code like this:
impl_web! {
impl HelloWorld {
#[get("/tower-web")]
fn hello_world(&self) -> Result<HelloResponse, ()> {
Ok(HelloResponse)
}
}
}
fn warp_routes() -> impl Filter<...> {
warp::get().and(warp::path("warp")).map(|| "hello world")
}
fn main() {
ServiceBuilder::new()
.resource(HelloWorld)
.resource(warp_routes())
.run(&addr)
.unwrap();
}
Another good change, which not related to the tower-web, but helps keep the warp small and simple as possible. Switch to use "hlist" implementation from the "frunk" crate. It already has necessary structures and traits for working with heterogeneous lists.
Proposed traits:
/// Filter conversion into tower-web resource.
trait IntoResource {
type Output: Resource;
fn into_resource(self) -> Self::Output;
}
/// Rejection conversion into tower-web error.
impl Into<Error> for Rejection {...};
/// The filter which uses frunk's hlists for Input and Output.
trait Filter<INPUT: Hlist> {
type Extract: Hlist;
type Output; // usually would be <INPUT as Add<Self::Extract>>::Output;
type Future: Future<Item = Self::Output, Error = Rejection>;
fn call(&self) -> Self::Future;
}
To: @seanmonstar
warp 0.2 has been released, with the interop between Filter and Service established.
@carllerche opened https://github.com/carllerche/tower-web/issues/218 in July 2019, and in one of the comments referred:
At a high level, my goal is to reduce tower-web to the macro stuff that will generate something... the exact details of what that something is is TBD.
since tower-web is still using futures 0.1 and tower::Service 0.1, should we port it's middlewares to warp, or should they rather be ported to the tower repo?
Most helpful comment
warp 0.2 has been released, with the interop between
FilterandServiceestablished.@carllerche opened https://github.com/carllerche/tower-web/issues/218 in July 2019, and in one of the comments referred:
since tower-web is still using futures 0.1 and tower::Service 0.1, should we port it's middlewares to warp, or should they rather be ported to the tower repo?