routerify 1.0.4

A lightweight and modular router implementation with middleware support for the Rust HTTP library hyper.rs.
Documentation

Github Actions Status crates.io Documentation Contributors MIT

Routerify

The Routerify provides a lightweight and modular router implementation with middleware support for the Rust HTTP library hyper.rs.

There are a lot of web server frameworks for Rust applications out there and hyper.rs being comparably very fast and ready for production use is one of them, and it provides only low level API. It doesn't provide any complex routing feature. So, Routerify extends the hyper.rs library by providing that missing feature without compromising any performance.

The Routerify offers the following features:

  • 📡 Allows defining complex routing logic.
  • 🔨 Provides middleware support.
  • 🌀 Supports Route Parameters.
  • 🚀 No performance compromising when integrated with hyper.rs.
  • 🍺 It supports any response body type as long as it implements the HttpBody trait.
  • ❗ Provides a flexible error handling strategy.
  • 🍗 Exhaustive examples and well documented.

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

Install

Add this to your Cargo.toml file:

[dependencies]
routerify = "1.0"

Basic Example

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

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

// A handler for "/" page.
async fn home_handler(_: Request<Body>) -> Result<Response<Body>, Infallible> {
    Ok(Response::new(Body::from("Home page")))
}

// A handler for "/about" page.
async fn about_handler(_: Request<Body>) -> Result<Response<Body>, Infallible> {
    Ok(Response::new(Body::from("About page")))
}

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

// Create a `Router<Body, Infallible>` for response body type `hyper::Body` and for handler error type `Infallible`.
fn router() -> Router<Body, Infallible> {
    // 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()
        .middleware(Middleware::pre(logger))
        .get("/", home_handler)
        .get("/about", about_handler)
        .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);

    // 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 common examples.

Contributing

Your PRs and suggestions are always welcome.