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