3个版本

使用旧的Rust 2015

0.1.2 2018年7月28日
0.1.1 2018年7月17日
0.1.0 2018年7月17日

#693 in 异步

45 每月下载

BSD-3-Clause

81KB
1.5K SLoC

Radix-Router

Build Status Released API docs

Radix-Router是julienschmidt/httprouter的Rust移植版。

使用方法

这只是个快速介绍。

让我们从一个 hello world 示例开始

extern crate futures;
extern crate hyper;
extern crate pretty_env_logger;
extern crate radix_router;

use futures::future;
use hyper::rt::{self, Future};
use hyper::{Body, Request, Response, Server};
use radix_router::router::{BoxFut, Params, Router, Handler};

fn index(_: Request<Body>, _: Params) -> BoxFut {
    let res = Response::builder().body("welcome!\n".into()).unwrap();
    Box::new(future::ok(res))
}

fn hello(_: Request<Body>, ps: Params) -> BoxFut {
    // let name = ps.by_name("name").unwrap();
    let name = &ps[0];
    let res = Response::builder()
        .body(format!("hello, {}!\n", name).into())
        .unwrap();
    Box::new(future::ok(res))
}

fn main() {
    pretty_env_logger::init();

    let addr = ([127, 0, 0, 1], 3000).into();

    // new_service is run for each connection, creating a 'service'
    // to handle requests for that specific connection.
    let new_service = move || {
        // This is the `Service` that will handle the connection.
        let mut router: Router<Handler> = Router::new();
        router.get("/", Box::new(index));
        router.get("/hello/:name", Box::new(hello));
        router
    };

    let server = Server::bind(&addr)
        .serve(new_service)
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Listening on http://{}", addr);

    rt::run(server);
}

处理器

处理器可以是任何东西。你可以存储一个 T 并获取一个 Option<&T>。注意 &T 是不可变的。我们提供了一个默认的 radix_router::router::Handler,它可以是一个 fnclosure。使用闭包时,你可以捕获外部参数。例如

router.get("/", Box::new(get_echo));
router.post("/echo", Box::new(post_echo));
router.post("/echo/uppercase", Box::new(post_echo_uppercase));
router.post("/echo/reversed", Box::new(post_echo_reversed));
router.get("/some", Box::new(move |_, _| -> BoxFut {
    Box::new(future::ok(
        Response::builder().body(some_str.into()).unwrap(),
    ))
}));

命名参数

:name 是一个 命名参数。这些值可以通过 Option<Params> 获取,它是一个 Param 的包装切片。你可以通过切片中的索引或使用 by_name(name) 方法来获取参数的值。

命名参数只匹配单个路径段

Pattern: /user/:user

 /user/gordon              match
 /user/you                 match
 /user/gordon/profile      no match
 /user/                    no match

注意:由于这个路由器只有显式匹配,你不能为同一个路径段注册静态路由和参数。例如,你不能在同一请求方法下同时注册 /user/new/user/:user 这两种模式。不同请求方法的路由是相互独立的。

捕获所有参数

第二种是 捕获所有 参数,形式为 *name。正如其名所示,它们匹配所有内容。因此,它们必须始终位于模式的 末尾

Pattern: /src/*filepath

 /src/                     match
 /src/somefile.go          match
 /src/subdir/somefile.go   match

静态文件

你可以使用

router.serve_files("/examples/*filepath", "examples");

示例

编写了一个回声服务器示例。您可以通过运行以下命令来测试它:

$ cargo run --example echo
$ curl http://127.0.0.1:3000/echo
Try POSTing data to /echo

$ curl -d "param1=1&param2=2" -X POST http://127.0.0.1:3000/echo
param1=1&param2=2

依赖项

~5.5MB
~99K SLoC