I'm looking at examples for how to implement a middleware in Actix Web. They show:
impl<S, B> Transform<S> for SayHi
where
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Request = ServiceRequest;
type Response = ServiceResponse<B>;
type Error = Error;
type InitError = ();
type Transform = SayHiMiddleware<S>;
type Future = FutureResult<Self::Transform, Self::InitError>;
fn new_transform(&self, service: S) -> Self::Future {
ok(SayHiMiddleware { service })
}
}
I'm having some trouble understanding the line:
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>
Is it saying that S
is bound by the Service
trait and in that trait there is a type named Request
and in THIS case Request
is actually a ServiceRequest
?
If so, why is there a need to specify type Request = ServiceRequest;
in the block?
Is it saying that
S
is bound by theService
trait and in that trait there is a type namedRequest
and in THIS caseRequest
is actually aServiceRequest
?
There are two traits, Transform
and Service
which both have an associated type called Request
. These aren't related.
If so, why is there a need to specify
type Request = ServiceRequest;
in the block?
By writing this implementation of Transform
for SayHi
, you are actually creating that relationship. You have defined what these associated type are, for an implementation that is only valid when all of the conditions in the where
clause are met.