2个版本
| 0.0.2 | 2023年10月19日 |
|---|---|
| 0.0.1 | 2023年8月16日 |
#470 in HTTP服务器
120KB
2.5K SLoC
另一个HTTP框架
警告:YAHF只在nightly版本下工作,直到
RPITIT稳定
YAHF的目标是提供良好的开发者体验,并且易于扩展。
目录
功能
- 无宏路由API
- 可预测的错误处理
- 处理器内建的本地序列化和反序列化
- 友好的语法
示例
Hello world的YAHF是
use yahf::server::Server;
#[tokio::main]
async fn main() {
let server = Server::new().get(
"/",
|| async { "Hello world".to_string() },
&(),
&String::with_capacity(0),
);
server
.listen(([127, 0, 0, 1], 8000).into())
.await
.unwrap();
}
路由
Router用于将处理器绑定到路径。
use yahf::router::Router;
// Router
let router = Router::new()
.get("/", root_get, &(), &())
.get("/foo", foo_get, &(), &())
.post("/foo", foo_post, &(), &())
.delete("/foo/bar", bar_delete, &(), &());
// calls respectively each of these handlers
async fn root_get() {}
async fn foo_get() {}
async fn foo_post() {}
async fn bar_delete() {}
处理器
在YAHF上,一个handler是一个用于处理Route的异步函数。一个可接受的handler实现了Runner特质。默认支持以下签名
async fn handler1() -> ResponseBody {todo!()}
async fn handler2() -> Response<ResponseBody> {todo!()}
async fn handler3(req: RequestBody) -> ResponseBody {todo!()}
async fn handler4(req: Request<RequestBody>) -> ResponseBody {todo!()}
async fn handler5(req: RequestBody) -> Response<ResponseBody> {todo!()}
async fn handler6(req: Request<RequestBody>) -> Response<ResponseBody> {todo!()}
async fn handler7() -> Result<ResponseBody> {todo!()}
async fn handler8() -> Result<Response<ResponseBody>> {todo!()}
async fn handler9(req: Result<RequestBody>) -> Result<ResponseBody> {todo!()}
async fn handler10(req: Result<Request<RequestBody>>) -> Result<ResponseBody> {todo!()}
async fn handler11(req: Result<RequestBody>) -> Result<Response<ResponseBody>> {todo!()}
async fn handler12(req: Result<Request<RequestBody>>) -> Result<Response<ResponseBody>> {todo!()}
所有这些签名都来自RunnerInput和RunnerOutput的实现。
可扩展性
YAHF handlers 是按模块化设计的。一个 handler 被分解为四个模块:一个正文 deserializer,一个正文 serializer,arguments,以及一个 response。这些模块通过 Runner 特性粘合在一起。向处理器添加新功能只需实现这些特性之一。有关更多详细信息,请查看特性文档
中间件
Middleware 是异步函数,将在 handler 之前或之后运行。当与 Router 或 Server 结合使用时,这些函数非常有用,可以重用逻辑并创建 "pipelines"。
示例
```rust use serde::Deserialize; use serde::Serialize; use yahf::handler::Json; use yahf::request::Request; use yahf::result::Result; use yahf::response::Response; use yahf::router::Router; use yahf::server::Server;use std::time; use std::time::UNIX_EPOCH; #[derive(Debug, Deserialize, Serialize)] struct ComputationBody { value: u32, }
// 打印时间、方法和请求的路径 async fn log_middleware(req: Result<Request>) -> Result<Request> { match req.into_inner() { Ok(req) => { println!( "{} - {} - {}", time::SystemTime::now() .duration_since(UNIX_EPOCH) .expect("Negative time") .as_millis(), req.method().as_str(), req.uri().path() );
Ok(req).into()
}
Err(err) => Err(err).into(),
}
}
// 处理任何可能的错误 async fn log_error(res: Result<Response>) -> Result<Response> { match res.into_inner() { Err(err) => { println!( "{} - {}", time::SystemTime::now() .duration_since(UNIX_EPOCH) .expect("Negative time") .as_millis(), err.code(), ); Err(err).into() } ok => ok.into(), } }
// 使用 ComputationBody 计算某些内容 async fn some_computation(req: ComputationBody) -> ComputationBody { ComputationBody { value: req.value + 1, } }
// 设置一个具有 Middlewares 的 Router。// 路由 / 将成为:log_middleware -> some_computation -> log_middleware let router = Router::new() .pre(log_middleware) .after(log_error) .get("/", some_computation, &Json::new(), &Json::new()); ``` 更多示例 这里
示例
该存储库包含 说明示例,展示了所有组件的集成
版本 1.0.0 的目标
YAHF遵循SemVer。
版本 1.0.0 的目标是拥有一个稳定的项目,可以处理现实世界的问题,具有良好的开发者体验,并且可以扩展项目以满足任何需求。
本版本的目标特性包括
- 可组合的路由系统;
- 中间件函数;
- 支持或不支持安全的 HTTP/1.1。
依赖关系
~14–26MB
~471K SLoC