Github Actions Status crates.io Documentation Contributors MIT

Routerify

Routerify provides a lightweight, idiomatic, composable and modular router implementation with middleware support for the Rust HTTP library hyper.

Routerify's core features:

To generate a quick server app using Routerify and hyper, please check out hyper-routerify-server-template.

Compiler support: requires rustc 1.48+

Benchmarks

| Framework | Language | Requests/sec | |----------------|-------------|--------------| | hyper v0.14 | Rust 1.50.0 | 144,583 | | routerify v2.0.0 with hyper v0.14 | Rust 1.50.0 | 144,621 | | actix-web v3 | Rust 1.50.0 | 131,292 | | warp v0.3 | Rust 1.50.0 | 145,362 | | go-httprouter, branch master | Go 1.16 | 130,662 | | Rocket, branch master | Rust 1.50.0 | 130,045 |

For more info, please visit Benchmarks.

Install

Add this to your Cargo.toml file:

toml [dependencies] routerify = "2.0.2" hyper = "0.14" tokio = { version = "1", features = ["full"] }

Basic Example

A simple example using Routerify with hyper would look like the following:

```rust use hyper::{Body, Request, Response, Server, StatusCode}; // Import the routerify prelude traits. use routerify::prelude::*; use routerify::{Middleware, Router, RouterService, RequestInfo}; use std::{convert::Infallible, net::SocketAddr};

// Define an app state to share it across the route handlers and middlewares. struct State(u64);

// A handler for "/" page. async fn home_handler(req: Request) -> Result, Infallible> { // Access the app state. let state = req.data::().unwrap(); println!("State value: {}", state.0);

Ok(Response::new(Body::from("Home page")))

}

// A handler for "/users/:userId" page. async fn userhandler(req: Request) -> Result, Infallible> { let userid = req.param("userId").unwrap(); Ok(Response::new(Body::from(format!("Hello {}", user_id)))) }

// A middleware which logs an http request. async fn logger(req: Request) -> Result, Infallible> { println!("{} {} {}", req.remote_addr(), req.method(), req.uri().path()); Ok(req) }

// Define an error handler function which will accept the routerify::Error // and the request information and generates an appropriate response. async fn errorhandler(err: routerify::RouteError, _: RequestInfo) -> Response { eprintln!("{}", err); Response::builder() .status(StatusCode::INTERNALSERVER_ERROR) .body(Body::from(format!("Something went wrong: {}", err))) .unwrap() }

// Create a Router<Body, Infallible> for response body type hyper::Body // and for handler error type Infallible. fn router() -> Router { // Create a router and specify the logger middleware and the handlers. // Here, "Middleware::pre" means we're adding a pre middleware which will be executed // before any route handlers. Router::builder() // Specify the state data which will be available to every route handlers, // error handler and middlewares. .data(State(100)) .middleware(Middleware::pre(logger)) .get("/", homehandler) .get("/users/:userId", userhandler) .errhandlerwithinfo(errorhandler) .build() .unwrap() }

[tokio::main]

async fn main() { let router = router();

// Create a Service from the router above to handle incoming requests.
let service = RouterService::new(router).unwrap();

// The address on which the server will be listening.
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

// Create a server by passing the created service to `.serve` method.
let server = Server::bind(&addr).serve(service);

println!("App is running on: {}", addr);
if let Err(err) = server.await {
    eprintln!("Server error: {}", err);

} } ```

Documentation

Please visit: Docs for an exhaustive documentation.

Examples

The examples.

Contributing

Your PRs and suggestions are always welcome.