#http #http-framework #http-service #web #server

aero

为构建 Rust HTTP 服务而设计的渐进式、惯用和最小化框架

4 个版本

0.1.4 2022年6月5日
0.1.3 2022年6月4日
0.1.1 2022年6月4日
0.1.0 2022年6月4日

#587HTTP 服务器

MIT 许可证

40KB
358

Aero

crates.io

🚀 为构建 Rust HTTP 服务而设计的渐进式、惯用和最小化框架。

  • 惯用路由器
  • 可组合中间件
fn main() {
    let mut app = Aero::new("127.0.0.1:3000");

    app.get("/", |ctx: &mut Context, next: Next| {
        ctx.send_text("Hello, world!");
    });

    app.get("/hello", |ctx: &mut Context, next: Next| {
        ctx.send_text("Hello, world!");
    });

    println!("Listening on http://{}", app.socket_addr);

    tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(app.run());
}

正在开发...

  • 干净代码
  • 响应 JSON
  • 路由
  • 请求体解析器
  • 文件组织
  • API 组织
  • 发布
  • 测试

安装

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

aero = "0.1.3"

开发

cargo fmt -- */**.rs
cargo run

使用

  • 路由器

let mut app = Aero::new("127.0.0.1:3000");

let mut router = Router::new("/api");
router.get("/book", |ctx: &mut Context, next: Next| {
    ctx.send_text("hello, is's /api/book");
    next(ctx);
});

app.mount(router);

println!("Listening on http://{}", app.socket_addr);
  • JSON 响应

#[derive(Serialize, Deserialize)]
pub struct Book {
    id: i32,
    name: String,
    price: f32,
}

let mut app = Aero::new("127.0.0.1:3000");

let mut router = Router::new("/api");
router.get("/book", |ctx: &mut Context, next: Next| {
    ctx.send_json(Book {
        id: 123,
        name: "asd".to_string(),
        price: 123.3,
    });
    next(ctx);
});
app.mount(router);

app.get("/hello", |ctx: &mut Context, next: Next| {
    ctx.send_text("Hello, world!");
});

println!("Listening on http://{}", app.socket_addr);
  • 中间件

let mut app = Aero::new("127.0.0.1:3000");

app.hold("/", |ctx: &mut Context, next: Next| {
    println!("middleware start -> {}", ctx.req.path);
    next(ctx);
    println!("middleware end -> {}", ctx.req.path);
});

app.hold("/", |ctx: &mut Context, next: Next| {
    let start = Instant::now();
    next(ctx);
    let duration = start.elapsed();
    println!(
        "[access] {} {} cost {:?}ms",
        ctx.req.method,
        ctx.req.path,
        duration.as_millis()
    );
});

app.get("/hello", |ctx: &mut Context, next: Next| {
    // some heavy task
    thread::sleep(Duration::from_millis(100));
    ctx.send_text("Hello, world!");
});

println!("Listening on http://{}", app.socket_addr);

示例列表在 examples

基准测试

Cooper@CooperdeMBP Rust % autocannon http://127.0.0.1:3000/api/shipping/orders
Running 10s test @ http://127.0.0.1:3000/api/shipping/orders
10 connections


┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬──────┐
│ Stat    │ 2.5%50%97.5%99%  │ Avg     │ Stdev   │ Max  │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼──────┤
│ Latency │ 0 ms │ 0 ms │ 0 ms  │ 0 ms │ 0.01 ms │ 0.04 ms │ 8 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴──────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%2.5%50%97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 46431464315279953887524002055.7946410   │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 15.2 MB15.2 MB17.3 MB17.6 MB17.1 MB674 kB  │ 15.2 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 10

524k requests in 10.01s, 171 MB read

许可证

MIT

依赖项

~4–11MB
~107K SLoC