Router

Struct Router 

Source
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

Source

pub fn new() -> Self

Creates a new, empty router.

Source

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" });
Source

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);
Source

pub async fn dispatch(&self, req: Request) -> Response

Dispatches an incoming request to the appropriate route handler.

Source

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());
Source

pub fn signals(&self) -> &SignalArbiter

Available on crate feature signals only.

Returns a reference to the signal arbiter.

Source

pub fn signal_arbiter(&self) -> SignalArbiter

Available on crate feature signals only.

Returns a clone of the signal arbiter, useful for sharing through state.

Source

pub fn on_signal<F, Fut>(&self, id: impl Into<String>, handler: F)
where F: Fn(Signal) -> Fut + Send + Sync + 'static, Fut: Future<Output = ()> + Send + 'static,

Available on crate feature signals only.

Registers a handler for a named signal on this router’s arbiter.

Source

pub async fn emit_signal(&self, signal: Signal)

Available on crate feature signals only.

Emits a signal through this router’s arbiter.

Source

pub fn middleware<F, Fut, R>(&self, f: F) -> &Self
where F: Fn(Request, Next) -> Fut + Clone + Send + Sync + 'static, Fut: Future<Output = R> + Send + 'static, R: Responder + Send + 'static,

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()
    }
});
Source

pub fn fallback<F, Fut, R>(&mut self, handler: F) -> &mut Self
where F: Fn(Request) -> Fut + Clone + Send + Sync + 'static, Fut: Future<Output = R> + Send + 'static, R: Responder + Send + 'static,

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);
Source

pub fn fallback_with_extractors<H, T>(&mut self, handler: H) -> &mut Self
where 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);
Source

pub fn plugin<P>(&mut self, plugin: P) -> &mut Self
where P: TakoPlugin + Clone + Send + Sync + 'static,

Available on crate feature 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);
Source

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);

Auto Trait Implementations§

§

impl !Freeze for Router

§

impl !RefUnwindSafe for Router

§

impl Send for Router

§

impl Sync for Router

§

impl Unpin for Router

§

impl !UnwindSafe for Router

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,