Trait poem::middleware::Middleware[][src]

pub trait Middleware<E: Endpoint> {
    type Output: Endpoint;
    fn transform(&self, ep: E) -> Self::Output;
}
Expand description

Represents a middleware trait.

Example

use poem::{handler, web::Data, Endpoint, EndpointExt, Middleware, Request};

/// A middleware that extract token from HTTP headers.
struct TokenMiddleware;

impl<E: Endpoint> Middleware<E> for TokenMiddleware {
    type Output = TokenMiddlewareImpl<E>;

    fn transform(&self, ep: E) -> Self::Output {
        TokenMiddlewareImpl { ep }
    }
}

/// The new endpoint type generated by the TokenMiddleware.
struct TokenMiddlewareImpl<E> {
    ep: E,
}

const TOKEN_HEADER: &str = "X-Token";

/// Token data
struct Token(String);

#[poem::async_trait]
impl<E: Endpoint> Endpoint for TokenMiddlewareImpl<E> {
    type Output = E::Output;

    async fn call(&self, mut req: Request) -> Self::Output {
        if let Some(value) = req
            .headers()
            .get(TOKEN_HEADER)
            .and_then(|value| value.to_str().ok())
        {
            // Insert token data to extensions of request.
            let token = value.to_string();
            req.extensions_mut().insert(Token(token));
        }

        // call the inner endpoint.
        self.ep.call(req).await
    }
}

#[handler]
async fn index(Data(token): Data<&Token>) -> String {
    token.0.clone()
}

// Use the `TokenMiddleware` middleware to convert the `index` endpoint.
let ep = index.with(TokenMiddleware);

let mut resp = ep
    .call(Request::builder().header(TOKEN_HEADER, "abc").finish())
    .await;
assert_eq!(resp.take_body().into_string().await.unwrap(), "abc");

Associated Types

New endpoint type.

If you don’t know what type to use, then you can use Box<dyn Endpoint>, which will bring some performance loss, but it is insignificant.

Required methods

Transform the input Endpoint to another one.

Implementations on Foreign Types

Implementors