Hello World 详解
完整代码
`src/main.rs`:
use webx::*;
// ── 第一步:定义 Request ──
struct HelloRequest;
// ── 第二步:标注路由 ──
#[get("/hello")]
impl IRequest<String> for HelloRequest {}
// ── 第三步:实现 Handler ──
#[derive(Default)]
struct HelloHandler;
#[handler]
#[async_trait]
impl IRequestHandler<HelloRequest, String> for HelloHandler {
async fn handle(&self, _req: HelloRequest) -> Result<String> {
Ok("Hello, World! Welcome to rust-webx.".to_string())
}
}
// ── 第四步:启动 Host ──
#[tokio::main]
async fn main() {
Host::builder()
.build()
.run()
.await
.expect("Server failed");
}
运行后访问 `http://localhost:5000/hello`,得到 JSON 字符串响应。
四步模式深度解读
第一步:定义 Request
struct HelloRequest;
`HelloRequest` 是**零大小类型(ZST)**,承载「这是一个获取问候语的请求」的语义。无路径参数、无 Body 时,struct 可以为空。
Request 结构体的字段将在有参数时发挥作用(路径参数、Query、Body)。
第二步:标注路由
#[get("/hello")]
impl IRequest<String> for HelloRequest {}
三个关键信息在这一行确定:
| 元素 | 含义 | |------|------| | `#[get("/hello")]` | HTTP GET,路径 `/hello` | | `impl IRequest<String>` | 响应类型为 `String`,框架序列化为 JSON | | 标注在 `impl` 块上 | **必须**标注在 impl 块,而非 struct(常见错误) |
编译时,`inventory` 收集此路由元数据;`Host::build()` 时自动注册到 Router。
第三步:实现 Handler
#[derive(Default)]
struct HelloHandler;
#[handler]
#[async_trait]
impl IRequestHandler<HelloRequest, String> for HelloHandler {
async fn handle(&self, _req: HelloRequest) -> Result<String> { ... }
}
| 元素 | 含义 | |------|------| | `IRequestHandler<HelloRequest, String>` | 处理 `HelloRequest`,返回 `String` | | `#[derive(Default)]` | `#[handler]` 宏要求 Handler 可默认构造 | | `#[handler]` | 编译时向 DI 注册 `dyn IRequestHandler<HelloRequest, String>` | | `Result<String>` | 成功返回数据,失败返回 `Error`(自动映射 HTTP 状态码) |
第四步:启动 Host
Host::builder().build().run().await
`build()` 执行的关键工作:
1. 加载 `appsettings.json` 2. 扫描 `inventory` 收集的所有路由 3. 扫描 `#[handler]` 注册的 Handler 4. 构建 DI 容器与中间件管道 5. 创建 Trie 路由器
`run()` 启动 HTTP 监听器(地址来自 `App.Urls` 配置)。
背后发生了什么
sequenceDiagram
participant Client
participant Pipeline as 中间件管道
participant Router
participant Endpoint
participant Handler
Client->>Pipeline: GET /hello
Pipeline->>Router: 匹配路由
Router->>Endpoint: HelloRequest 端点
Endpoint->>Handler: DI 解析 HelloHandler
Handler-->>Endpoint: Ok("Hello...")
Endpoint-->>Client: 200 JSON
你写的代码只涉及 Request + Handler;路由匹配、DI 解析、JSON 序列化均由框架完成。
常见变体
返回 204 No Content
#[delete("/items/{id}")]
impl IRequest<()> for DeleteItemRequest {}
impl IRequestHandler<DeleteItemRequest, ()> for DeleteItemHandler {
async fn handle(&self, req: DeleteItemRequest) -> Result<()> {
// 删除逻辑
Ok(())
}
}
`IRequest<()>` 表示响应体为空,HTTP 状态码 204。
返回自定义 DTO
#[derive(Serialize)]
struct GreetingDto {
message: String,
version: String,
}
#[get("/hello")]
impl IRequest<GreetingDto> for HelloRequest {}
小结
Hello World 看似简单,实则展示了 rust-webx 的**核心契约**:Request 声明路由与响应类型,Handler 实现业务逻辑,框架负责一切管线工作。
下一节:[第一个 CRUD API](first-crud.md)