Trait Middleware

Source
pub trait Middleware:
    Send
    + Sync
    + 'static {
    // Required method
    fn call(
        &self,
        req: Request,
        next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
}
Expand description

Trait for implementing middleware components.

Middleware can intercept requests before they reach handlers and modify responses before they’re sent to clients. This trait provides a standard interface for all middleware components.

§Examples

§Authentication Middleware

use torch_web::{Request, Response, middleware::Middleware};
use std::pin::Pin;
use std::future::Future;

struct AuthMiddleware {
    secret_key: String,
}

impl AuthMiddleware {
    fn new(secret_key: String) -> Self {
        Self { secret_key }
    }
}

impl Middleware for AuthMiddleware {
    fn call(
        &self,
        req: Request,
        next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> {
        Box::pin(async move {
            // Check for authorization header
            if let Some(auth_header) = req.header("authorization") {
                if auth_header.starts_with("Bearer ") {
                    // Validate token here...
                    return next(req).await;
                }
            }

            Response::unauthorized().body("Authentication required")
        })
    }
}

§CORS Middleware

use torch_web::{Request, Response, middleware::Middleware};
use std::pin::Pin;
use std::future::Future;

struct CorsMiddleware;

impl Middleware for CorsMiddleware {
    fn call(
        &self,
        req: Request,
        next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> {
        Box::pin(async move {
            let mut response = next(req).await;
            response = response
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
                .header("Access-Control-Allow-Headers", "Content-Type, Authorization");
            response
        })
    }
}

Required Methods§

Source

fn call( &self, req: Request, next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>, ) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>>

Processes a request through the middleware chain.

This method receives the current request and a next function that continues processing through the remaining middleware and eventually to the route handler.

§Parameters
  • req - The HTTP request to process
  • next - Function to call the next middleware or handler in the chain
§Returns

Returns a Future that resolves to the HTTP response. The middleware can modify the request before calling next, modify the response after calling next, or return early without calling next at all.

§Examples
use torch_web::{Request, Response, middleware::Middleware};
use std::pin::Pin;
use std::future::Future;

struct TimingMiddleware;

impl Middleware for TimingMiddleware {
    fn call(
        &self,
        req: Request,
        next: Box<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> + Send + Sync>,
    ) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>> {
        Box::pin(async move {
            let start = std::time::Instant::now();
            let response = next(req).await;
            let duration = start.elapsed();

            println!("Request took {:?}", duration);
            response.header("X-Response-Time", &format!("{}ms", duration.as_millis()))
        })
    }
}

Implementors§