-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Simplified Handle
trait
#1275
Simplified Handle
trait
#1275
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1275 +/- ##
==========================================
- Coverage 80.47% 80.43% -0.04%
==========================================
Files 159 159
Lines 18541 18550 +9
==========================================
Hits 14921 14921
- Misses 3620 3629 +9
Continue to review full report at Codecov.
|
Your i dont see how |
I'm not looking to replace the I've been investigating upgrading one of my projects from Another possibility is to look at using tower's service trait, but possibly behind a feature flag or as an external crate. |
|
Yep, but the challenge with that is it's a free floating function. If you could replace |
you can replace FnMut with any struct that implements Service trait. |
Yes you can, but not without having to define a I.e, without this change this is the bare minimum to have a struct somewhere in your web app instead of a function. Lots of boilerplate: impl Service for TestService {
type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = Error;
type Future = Ready<Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: ServiceRequest) -> Self::Future {
ok(req.into_response(HttpResponse::Ok().body("Test")))
}
}
impl ServiceFactory for TestService {
type Request = ServiceRequest;
type Response = ServiceResponse;
type Error = Error;
type Future = Ready<Result<TestService, ()>>;
type Config = ();
type InitError = ();
type Service = TestService;
fn new_service(&self, _config: ()) -> Self::Future {
ok(self.clone())
}
} If there is a simpler way than that currently, I could not find it in documentation or examples or can be lead there by the compiler. Compare that with the handle trait: impl Handle for TestService {
type Future = Ready<Result<ServiceResponse, Error>>;
fn call(&mut self, req: ServiceRequest) -> Self::Future {
ok(req.into_response(HttpResponse::Ok().body("Test")))
}
} 27 Lines of code vs. 7 and a lot more readable. |
You can use fn_factory |
As discussed in the chat, there is no easy migration path for handlers from
0.7
. The only way you can respond to requests is free floating functions. You should be able to impl a trait on structs to easily encapsulate data and use this accordingly.This PR, while it probably won't be accepted initially, is my take on what I would like to see to simplify this process.
It defines a much simpler trait than the existing
Service
trait which requires 2 trait impls and a number of associated types.The trait is as follows (Could possibly be generic on
Error
):Then a struct (as we can't use specialisation yet) which requires that your struct must be clone so that service factory can be implemented. There might be other ways to accomplish this.
Example of usage: