#hyper #middleware #router #routing #hyper-http #http-middleware

routerify

为 Rust HTTP 库 hyper.rs 提供一个轻量级、惯用、可组合和模块化的路由实现,支持中间件。

21 个版本 (稳定)

3.0.0 2021年12月24日
2.2.1 2021年12月24日
2.2.0 2021年7月21日
2.0.0 2021年3月14日
0.1.1 2020年3月24日

#38 in HTTP 服务器

Download history 11353/week @ 2024-03-14 9997/week @ 2024-03-21 8031/week @ 2024-03-28 10748/week @ 2024-04-04 9655/week @ 2024-04-11 16422/week @ 2024-04-18 18760/week @ 2024-04-25 17776/week @ 2024-05-02 19530/week @ 2024-05-09 22441/week @ 2024-05-16 23221/week @ 2024-05-23 25982/week @ 2024-05-30 21267/week @ 2024-06-06 20798/week @ 2024-06-13 23831/week @ 2024-06-20 20713/week @ 2024-06-27

91,939 每月下载次数
20 个 Crates 中使用 (直接使用 18 个)

MIT 许可证

140KB
1.5K SLoC

Github Actions Status crates.io Documentation Contributors MIT

Routerify

Routerify 为 Rust HTTP 库 hyper 提供了一个轻量级、惯用、可组合和模块化的路由实现,并支持中间件。

Routerify 的核心功能

要使用 Routerifyhyper 创建快速的服务器应用程序,请查看 hyper-routerify-server-template

编译器支持:需要 rustc 1.48+

基准测试

框架 语言 每秒请求数
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

更多信息请访问 基准测试

安装

将以下内容添加到您的 Cargo.toml 文件中

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

基本示例

以下是一个使用 Routerifyhyper 的简单示例:

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<Body>) -> Result<Response<Body>, Infallible> {
    // Access the app state.
    let state = req.data::<State>().unwrap();
    println!("State value: {}", state.0);

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

// A handler for "/users/:userId" page.
async fn user_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let user_id = 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<Body>) -> Result<Request<Body>, 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 error_handler(err: routerify::RouteError, _: RequestInfo) -> Response<Body> {
    eprintln!("{}", err);
    Response::builder()
        .status(StatusCode::INTERNAL_SERVER_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<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()
        // Specify the state data which will be available to every route handlers,
        // error handler and middlewares.
        .data(State(100))
        .middleware(Middleware::pre(logger))
        .get("/", home_handler)
        .get("/users/:userId", user_handler)
        .err_handler_with_info(error_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).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);
   }
}

文档

请访问:[文档](https://docs.rs/routerify) 获取完整文档。

示例

请参阅 示例

贡献

您的 PR 和建议总是受欢迎的。

依赖

~7–18MB
~218K SLoC