Trait Middleware

Source
pub trait Middleware<S> {
    type Request;
    type Response;
    type Error;
    type Service: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>;

    // Required method
    fn wrap(&self, inner: S) -> Self::Service;

    // Provided method
    fn chain<T>(self, middleware: T) -> Chain<Self, T>
       where T: Middleware<Self::Service>,
             Self: Sized { ... }
}
Expand description

Decorates a Service, transforming either the request or the response.

Often, many of the pieces needed for writing network applications can be reused across multiple services. The Middleware trait can be used to write reusable components that can be applied to very different kinds of services; for example, it can be applied to services operating on different protocols, and to both the client and server side of a network transaction.

§Log

Take request logging as an example:

use tower_service::Service;
use tower_web::middleware::Middleware;
use futures::{Future, Poll};

use std::fmt;

pub struct LogMiddleware {
    target: &'static str,
}

impl<S> Middleware<S> for LogMiddleware
where
    S: Service,
    S::Request: fmt::Debug,
{
    type Request = S::Request;
    type Response = S::Response;
    type Error = S::Error;
    type Service = LogService<S>;

    fn wrap(&self, service: S) -> LogService<S> {
        LogService {
            target: self.target,
            service
        }
    }
}

// This service implements the Log behavior
pub struct LogService<S> {
    target: &'static str,
    service: S,
}

impl<S> Service for LogService<S>
where
    S: Service,
    S::Request: fmt::Debug,
{
    type Request = S::Request;
    type Response = S::Response;
    type Error = S::Error;
    type Future = S::Future;

    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
        self.service.poll_ready()
    }

    fn call(&mut self, request: Self::Request) -> Self::Future {
        info!(target: self.target, "request = {:?}", request);
        self.service.call(request)
    }
}

The above log implementation is decoupled from the underlying protocol and is also decoupled from client or server concerns. In other words, the same log middleware could be used in either a client or a server.

Required Associated Types§

Source

type Request

The wrapped service request type

Source

type Response

The wrapped service response type

Source

type Error

The wrapped service’s error type

Source

type Service: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>

The wrapped service

Required Methods§

Source

fn wrap(&self, inner: S) -> Self::Service

Wrap the given service with the middleware, returning a new service that has been decorated with the middleware.

Provided Methods§

Source

fn chain<T>(self, middleware: T) -> Chain<Self, T>
where T: Middleware<Self::Service>, Self: Sized,

Return a new Middleware instance that applies both self and middleware to services being wrapped.

This defines a middleware stack.

Implementors§

Source§

impl<S> Middleware<S> for CorsMiddleware
where S: HttpService,

Source§

impl<S, Inner, Outer> Middleware<S> for Chain<Inner, Outer>
where S: Service, Inner: Middleware<S>, Outer: Middleware<Inner::Service>,

Source§

type Request = <Outer as Middleware<<Inner as Middleware<S>>::Service>>::Request

Source§

type Response = <Outer as Middleware<<Inner as Middleware<S>>::Service>>::Response

Source§

type Error = <Outer as Middleware<<Inner as Middleware<S>>::Service>>::Error

Source§

type Service = <Outer as Middleware<<Inner as Middleware<S>>::Service>>::Service

Source§

impl<S, RequestBody, ResponseBody> Middleware<S> for DeflateMiddleware
where S: Service<Request = Request<RequestBody>, Response = Response<ResponseBody>>, RequestBody: BufStream, ResponseBody: BufStream, S::Error: Error,

Source§

impl<S, RequestBody, ResponseBody> Middleware<S> for LogMiddleware
where S: Service<Request = Request<RequestBody>, Response = Response<ResponseBody>>, S::Error: Error,

Source§

type Request = Request<RequestBody>

Source§

type Response = Response<ResponseBody>

Source§

type Error = <S as Service>::Error

Source§

type Service = LogService<S>

Source§

impl<S: Service> Middleware<S> for Identity

Decorates a Service, transforming either the request or the response.