Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tower with MemoryStore

This is the smallest complete example. It defines a KeyExtractor, creates an explicit process-local Store, builds a policy, and composes the resulting Layer around a Tower service.

cargo run --example tower_memory --features memory

Complete source

use std::{convert::Infallible, error::Error, future::ready, time::Duration};

use http::{Request, Response};
use tower::{Layer, service_fn};
use tower_rate_limiter::{KeyExtractor, MemoryStore, RateLimitLayer};

#[derive(Clone, Copy)]
struct StaticClient;

impl KeyExtractor for StaticClient {
    type Key = String;

    fn extract<B>(&self, _request: &Request<B>) -> Result<Self::Key, tower_rate_limiter::RateLimitError> {
        Ok(String::from("example-client"))
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    dotenvy::dotenv().ok();

    let limiter = RateLimitLayer::builder(StaticClient)
        .policy_name("tower-example")
        .limit(100)
        .window(Duration::from_secs(60))
        .with_store(MemoryStore::new())
        .build()?;

    let _service = limiter.layer(service_fn(|_request: Request<()>| {
        ready(Ok::<Response<()>, Infallible>(Response::new(())))
    }));

    println!("constructed a Tower MemoryStore rate limiter");
    Ok(())
}

The static key deliberately puts every request in the same bucket. Replace it with an application-owned caller identity in a real service.