pub struct Router { /* private fields */ }Expand description
HTTP router for managing routes, middleware, and request dispatching.
The Router is the central component for routing HTTP requests to appropriate
handlers. It supports dynamic path parameters, middleware chains, plugin integration,
and global state management. Routes are matched based on HTTP method and path pattern,
with support for trailing slash redirection and parameter extraction.
§Examples
use tako::{router::Router, Method, responder::Responder, types::Request};
async fn index(_req: Request) -> impl Responder {
"Welcome to the home page!"
}
async fn user_profile(_req: Request) -> impl Responder {
"User profile page"
}
let mut router = Router::new();
router.route(Method::GET, "/", index);
router.route(Method::GET, "/users/{id}", user_profile);
router.state("app_name", "MyApp".to_string());Implementations§
Source§impl Router
impl Router
Sourcepub fn route<H, T>(
&mut self,
method: Method,
path: &str,
handler: H,
) -> Arc<Route>where
H: Handler<T> + Clone + 'static,
pub fn route<H, T>(
&mut self,
method: Method,
path: &str,
handler: H,
) -> Arc<Route>where
H: Handler<T> + Clone + 'static,
Registers a new route with the router.
Associates an HTTP method and path pattern with a handler function. The path
can contain dynamic segments using curly braces (e.g., /users/{id}), which
are extracted as parameters during request processing.
§Examples
use tako::{router::Router, Method, responder::Responder, types::Request};
async fn get_user(_req: Request) -> impl Responder {
"User details"
}
async fn create_user(_req: Request) -> impl Responder {
"User created"
}
let mut router = Router::new();
router.route(Method::GET, "/users/{id}", get_user);
router.route(Method::POST, "/users", create_user);
router.route(Method::GET, "/health", |_req| async { "OK" });Sourcepub fn route_with_tsr<H, T>(
&mut self,
method: Method,
path: &str,
handler: H,
) -> Arc<Route>where
H: Handler<T> + Clone + 'static,
pub fn route_with_tsr<H, T>(
&mut self,
method: Method,
path: &str,
handler: H,
) -> Arc<Route>where
H: Handler<T> + Clone + 'static,
Registers a route with trailing slash redirection enabled.
When TSR is enabled, requests to paths with or without trailing slashes are automatically redirected to the canonical version. This helps maintain consistent URLs and prevents duplicate content issues.
§Panics
Panics if called with the root path (“/”) since TSR is not applicable.
§Examples
use tako::{router::Router, Method, responder::Responder, types::Request};
async fn api_handler(_req: Request) -> impl Responder {
"API endpoint"
}
let mut router = Router::new();
// Both "/api" and "/api/" will redirect to the canonical form
router.route_with_tsr(Method::GET, "/api", api_handler);Sourcepub async fn dispatch(&self, req: Request) -> Response
pub async fn dispatch(&self, req: Request) -> Response
Dispatches an incoming request to the appropriate route handler.
Sourcepub fn state<T: Clone + Send + Sync + 'static>(&mut self, value: T)
pub fn state<T: Clone + Send + Sync + 'static>(&mut self, value: T)
Adds a value to the global type-based state accessible by all handlers.
Global state allows sharing data across different routes and middleware.
Values are stored by their concrete type and retrieved via the
State extractor or with
crate::state::get_state.
§Examples
use tako::router::Router;
#[derive(Clone)]
struct AppConfig { database_url: String, api_key: String }
let mut router = Router::new();
router.state(AppConfig {
database_url: "postgresql://localhost/mydb".to_string(),
api_key: "secret-key".to_string(),
});
// You can also store simple types by type:
router.state::<String>("1.0.0".to_string());Sourcepub fn signals(&self) -> &SignalArbiter
Available on crate feature signals only.
pub fn signals(&self) -> &SignalArbiter
signals only.Returns a reference to the signal arbiter.
Sourcepub fn signal_arbiter(&self) -> SignalArbiter
Available on crate feature signals only.
pub fn signal_arbiter(&self) -> SignalArbiter
signals only.Returns a clone of the signal arbiter, useful for sharing through state.
Sourcepub fn on_signal<F, Fut>(&self, id: impl Into<String>, handler: F)
Available on crate feature signals only.
pub fn on_signal<F, Fut>(&self, id: impl Into<String>, handler: F)
signals only.Registers a handler for a named signal on this router’s arbiter.
Sourcepub async fn emit_signal(&self, signal: Signal)
Available on crate feature signals only.
pub async fn emit_signal(&self, signal: Signal)
signals only.Emits a signal through this router’s arbiter.
Sourcepub fn middleware<F, Fut, R>(&self, f: F) -> &Self
pub fn middleware<F, Fut, R>(&self, f: F) -> &Self
Adds global middleware to the router.
Global middleware is executed for all routes in the order it was added, before any route-specific middleware. Middleware can modify requests, generate responses, or perform side effects like logging or authentication.
§Examples
use tako::{router::Router, middleware::Next, types::Request};
let mut router = Router::new();
// Logging middleware
router.middleware(|req, next| async move {
println!("Request: {} {}", req.method(), req.uri());
let response = next.run(req).await;
println!("Response: {}", response.status());
response
});
// Authentication middleware
router.middleware(|req, next| async move {
if req.headers().contains_key("authorization") {
next.run(req).await
} else {
"Unauthorized".into_response()
}
});Sourcepub fn fallback<F, Fut, R>(&mut self, handler: F) -> &mut Self
pub fn fallback<F, Fut, R>(&mut self, handler: F) -> &mut Self
Sets a fallback handler that will be executed when no route matches.
The fallback runs after global middlewares and can be used to implement custom 404 pages, catch-all logic, or method-independent handlers.
§Examples
use tako::{router::Router, Method, responder::Responder, types::Request};
async fn not_found(_req: Request) -> impl Responder { "Not Found" }
let mut router = Router::new();
router.route(Method::GET, "/", |_req| async { "Hello" });
router.fallback(not_found);Sourcepub fn fallback_with_extractors<H, T>(&mut self, handler: H) -> &mut Selfwhere
H: Handler<T> + Clone + 'static,
pub fn fallback_with_extractors<H, T>(&mut self, handler: H) -> &mut Selfwhere
H: Handler<T> + Clone + 'static,
Sets a fallback handler that supports extractors (like Path, Query, etc.).
Use this when your fallback needs to parse request data via extractors. If you
only need access to the raw Request, prefer fallback for simpler type inference.
§Examples
use tako::{router::Router, responder::Responder, extractors::{path::Path, query::Query}};
#[derive(serde::Deserialize)]
struct Q { q: Option<String> }
async fn fallback_with_q(Path(_p): Path<String>, Query(_q): Query<Q>) -> impl Responder {
"Not Found"
}
let mut router = Router::new();
router.fallback_with_extractors(fallback_with_q);Sourcepub fn plugin<P>(&mut self, plugin: P) -> &mut Self
Available on crate feature plugins only.
pub fn plugin<P>(&mut self, plugin: P) -> &mut Self
plugins only.Registers a plugin with the router.
Plugins extend the router’s functionality by providing additional features like compression, CORS handling, rate limiting, or custom behavior. Plugins are initialized once when the server starts.
§Examples
use tako::{router::Router, plugins::TakoPlugin};
use anyhow::Result;
struct LoggingPlugin;
impl TakoPlugin for LoggingPlugin {
fn name(&self) -> &'static str {
"logging"
}
fn setup(&self, _router: &Router) -> Result<()> {
println!("Logging plugin initialized");
Ok(())
}
}
let mut router = Router::new();
router.plugin(LoggingPlugin);Sourcepub fn merge(&mut self, other: Router)
pub fn merge(&mut self, other: Router)
Merges another router into this router.
This method combines routes and middleware from another router into the current one. Routes are copied over, and the other router’s global middleware is prepended to each merged route’s middleware chain.
§Examples
use tako::{router::Router, Method, responder::Responder, types::Request};
async fn api_handler(_req: Request) -> impl Responder {
"API response"
}
async fn web_handler(_req: Request) -> impl Responder {
"Web response"
}
// Create API router
let mut api_router = Router::new();
api_router.route(Method::GET, "/users", api_handler);
api_router.middleware(|req, next| async move {
println!("API middleware");
next.run(req).await
});
// Create main router and merge API router
let mut main_router = Router::new();
main_router.route(Method::GET, "/", web_handler);
main_router.merge(api_router);