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.