use axum::{routing::get, Router};
use tower_rate_tier::{Quota, RateTier, TierIdentity, TierLimitLayer};
#[tokio::main]
async fn main() {
let rate_tier = RateTier::builder()
.tier("free", Quota::per_minute(10))
.tier("pro", Quota::per_minute(100))
.tier("enterprise", Quota::unlimited())
.default_tier("free")
.build();
let layer = TierLimitLayer::new(rate_tier)
.identifier_fn(|headers| {
let api_key = headers.get("x-api-key")?.to_str().ok()?;
let tier = match api_key {
"pro-user" => "pro",
"enterprise-user" => "enterprise",
_ => "free",
};
Some(TierIdentity::new(api_key, tier))
})
.cost_fn(|req| match req.uri.path() {
"/api/search" => 5, _ => 1,
});
let app = Router::new()
.route("/api/users", get(list_users))
.route("/api/search", get(search))
.layer(layer);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
println!("Listening on http://localhost:3000");
axum::serve(listener, app).await.unwrap();
}
async fn list_users() -> &'static str {
"users list"
}
async fn search() -> &'static str {
"search results"
}