Skip to main content

per

Function per 

Source
pub fn per(
    max_requests: u32,
    window: Duration,
) -> FromFnLayer<fn(State<Arc<ThrottleState>>, Option<ConnectInfo<SocketAddr>>, Request, Next) -> Pin<Box<dyn Future<Output = Response> + Send>>, Arc<ThrottleState>, (State<Arc<ThrottleState>>, Option<ConnectInfo<SocketAddr>>, Request)>
Expand description

max_requests per window - the general form behind per_minute. Usable via Router::middleware(...) the same way csrf::verify/ DefaultBodyLimit::max(...) already are.

Returns the fully concrete FromFnLayer<...> type rather than impl tower::Layer<axum::routing::Route> + Clone + Send + 'static - tempting since that’s exactly what Router::middleware() requires, but an opaque impl Trait return only carries the bounds spelled out on it, not the other facts a caller in a different crate needs (that L::Service is itself Clone + Send + tower::Service<Request>, Router::middleware()’s real bound on L::Service) - those get erased at the opaque-type boundary, so demo/examples/blog’s own .middleware(throttle::per_minute(60)) call failed to type-check against impl Trait even though this exact value works fine passed directly. A concrete, nameable return type has no such boundary; every real trait impl on it stays visible everywhere. Same reason Router:: middleware()’s own doc comment says to call axum::middleware:: from_fn(handler) directly at the .middleware(...) call site instead of through a wrapping function - this file does the equivalent by keeping the concrete type nameable instead.