23 个版本

0.6.1 2022 年 1 月 17 日
0.5.1 2021 年 3 月 29 日
0.5.0 2020 年 4 月 2 日
0.5.0-rc.32020 年 3 月 28 日

HTTP 服务器 中排名第 1388

Download history 35/week @ 2024-03-13 31/week @ 2024-03-20 57/week @ 2024-03-27 75/week @ 2024-04-03 26/week @ 2024-04-10 36/week @ 2024-04-17 39/week @ 2024-04-24 30/week @ 2024-05-01 31/week @ 2024-05-08 42/week @ 2024-05-15 37/week @ 2024-05-22 46/week @ 2024-05-29 27/week @ 2024-06-05 35/week @ 2024-06-12 28/week @ 2024-06-19 23/week @ 2024-06-26

每月下载 116
12 Crates(直接使用 7 个)使用

MIT 许可证

70KB
1.5K SLoC

Stable Test codecov Rust Docs Crate version Download License: MIT

简介

Roa 框架的核心组件。

如果你是 roa 的初学者,请参阅 roa 框架文档

应用

一个 Roa 应用程序是一个以堆栈方式组合和执行中间件和端点的结构。

必做的 hello world 应用

use roa_core::App;
let app = App::new().end("Hello, World");

端点

端点是一个请求处理器。

roa_core 中有一些内置的端点。

  • 功能端点

    一个普通的函数端点是一个具有以下签名的异步函数: async fn(&mut Context) -> Result.

    use roa_core::{App, Context, Result};
    
    async fn endpoint(ctx: &mut Context) -> Result {
        Ok(())
    }
    
    let app = App::new().end(endpoint);
    
  • Ok 端点

    () 是一个始终返回 Ok(()) 的端点

    let app = roa_core::App::new().end(());
    
  • 状态端点

    Status 是一个始终返回 Err(Status) 的端点

    use roa_core::{App, status};
    use roa_core::http::StatusCode;
    let app = App::new().end(status!(StatusCode::BAD_REQUEST));
    
  • 字符串端点

    将字符串写入正文。

    use roa_core::App;
    
    let app = App::new().end("Hello, world"); // static slice
    let app = App::new().end("Hello, world".to_owned()); // string
    
  • 重定向端点

    重定向到 URI。

    use roa_core::App;
    use roa_core::http::Uri;
    
    let app = App::new().end("/target".parse::<Uri>().unwrap());
    

级联

以下示例以 "Hello World" 响应,但是请求流经 logging 中间件以标记请求何时开始,然后通过端点继续传递控制。当中间件调用 next.await 时,函数挂起并将控制权传递给下一个中间件或端点。端点被调用后,堆栈将展开,每个中间件都将恢复以执行其上游行为。

use roa_core::{App, Context, Result, Status, MiddlewareExt, Next};
use std::time::Instant;
use tracing::info;

let app = App::new().gate(logging).end("Hello, World");

async fn logging(ctx: &mut Context, next: Next<'_>) -> Result {
    let inbound = Instant::now();
    next.await?;
    info!("time elapsed: {} ms", inbound.elapsed().as_millis());
    Ok(())
}

状态处理

您可以捕获或直接抛出 next 返回的状态。

use roa_core::{App, Context, Result, Status, MiddlewareExt, Next, throw};
use roa_core::http::StatusCode;
        
let app = App::new().gate(catch).gate(gate).end(end);

async fn catch(ctx: &mut Context, next: Next<'_>) -> Result {
    // catch
    if let Err(status) = next.await {
        // teapot is ok
        if status.status_code != StatusCode::IM_A_TEAPOT {
            return Err(status);
        }
    }
    Ok(())
}
async fn gate(ctx: &mut Context, next: Next<'_>) -> Result {
    next.await?; // just throw
    unreachable!()
}

async fn end(ctx: &mut Context) -> Result {
    throw!(StatusCode::IM_A_TEAPOT, "I'm a teapot!")
}

status_handler

应用程序有一个 status_handler 来处理顶级中间件抛出的 Status。这是 status_handler

use roa_core::{Context, Status, Result, State};
pub fn status_handler<S: State>(ctx: &mut Context<S>, status: Status) {
    ctx.resp.status = status.status_code;
    if status.expose {
        ctx.resp.write(status.message);
    } else {
        tracing::error!("{}", status);
    }
}

HTTP 服务器。

使用 roa_core::accept 构建一个 HTTP 服务器。有关更多信息,请参阅 roa::tcp

依赖项

约 6.5–8.5MB
约 151K SLoC