Search code examples
rusttraitsactix-web

How to understand trait for implementing Actix Web middleware?


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?


Solution

  • 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?

    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.