关于 domain-web
domain-web 是用于设计 Rust Web 应用的技能,关注异步处理器、线程安全状态、请求生命周期、验证和可观测性,并介绍实现这些约束的框架、crate 与模式。
主要功能
- 01异步非阻塞处理器
- 02线程安全的共享应用状态
- 03按请求管理资源生命周期
- 04验证请求数据的提取器
- 05统一错误响应
- 06使用 tracing 与 Tower 中间件
适用场景
- 01设计避免阻塞的 HTTP 处理器
- 02在处理器线程间共享应用状态
- 03验证传入的请求数据
- 04用中间件组织横切逻辑
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ actionbook/ rust-skills --skill domain-web安装后在 Claude Code 中输入/domain-web确认已加载。
详细介绍
Web Domain
第 3 层:领域约束
领域约束 → 设计影响
| 领域规则 | 设计约束 | Rust 影响 |
|---|---|---|
| 无状态 HTTP | 不使用请求局部全局变量 | 在提取器中存储状态 |
| 并发 | 处理大量连接 | 异步、Send + Sync |
| 延迟 SLA | 快速响应 | 高效的所有权管理 |
| 安全 | 输入验证 | 类型安全的提取器 |
| 可观测性 | 请求追踪 | tracing + tower 层 |
关键约束
默认采用异步
RULE: Web handlers must not block
WHY: Block one task = block many requests
RUST: async/await, spawn_blocking for CPU work
状态管理
RULE: Shared state must be thread-safe
WHY: Handlers run on any thread
RUST: Arc<T>, Arc<RwLock<T>> for mutable
请求生命周期
RULE: Resources live only for request duration
WHY: Memory management, no leaks
RUST: Extractors, proper ownership
向下追溯 ↓
从约束追溯到设计(第 2 层):
"Need shared application state"
↓ m07-concurrency: Use Arc for thread-safe sharing
↓ m02-resource: Arc<RwLock<T>> for mutable state
"Need request validation"
↓ m05-type-driven: Validated extractors
↓ m06-error-handling: IntoResponse for errors
"Need middleware stack"
↓ m12-lifecycle: Tower layers
↓ m04-zero-cost: Trait-based composition
框架比较
| 框架 | 风格 | 最适合 |
|---|---|---|
| axum | 函数式、tower | 现代 API |
| actix-web | 基于 Actor | 高性能 |
| warp | 过滤器组合 | 可组合的 API |
| rocket | 宏驱动 | 快速开发 |
关键 Crate
| 用途 | Crate |
|---|---|
| HTTP 服务端 | axum、actix-web |
| HTTP 客户端 | reqwest |
| JSON | serde_json |
| 身份验证/JWT | jsonwebtoken |
| 会话 | tower-sessions |
| 数据库 | sqlx、diesel |
| 中间件 | tower |
设计模式
| 模式 | 用途 | 实现 |
|---|---|---|
| 提取器 | 请求解析 | State(db)、Json(payload) |
| 错误响应 | 统一错误 | impl IntoResponse |
| 中间件 | 横切关注点 | Tower 层 |
| 共享状态 | 应用配置 | Arc<AppState> |
代码模式:Axum 处理器
async fn handler(
State(db): State<Arc<DbPool>>,
Json(payload): Json<CreateUser>,
) -> Result<Json<User>, AppError> {
let user = db.create_user(&payload).await?;
Ok(Json(user))
}
// Error handling
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
Self::NotFound => (StatusCode::NOT_FOUND, "Not found"),
Self::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error"),
};
(status, Json(json!({"error": message}))).into_response()
}
}
常见错误
| 错误 | 违反的领域约束 | 修正方法 |
|---|---|---|
| 在处理器中阻塞 | 延迟激增 | spawn_blocking |
| 在状态中使用 Rc | 不满足 Send + Sync | 使用 Arc |
| 未进行验证 | 安全风险 | 使用类型安全的提取器 |
| 没有错误响应 | 用户体验差 | 实现 IntoResponse |
追溯到第 1 层
| 约束 | 第 2 层模式 | 第 1 层实现 |
|---|---|---|
| 异步处理器 | Async/await | tokio 运行时 |
| 线程安全的状态 | 共享状态 | Arc、Arc<RwLock> |
| 请求生命周期 | 提取器 | 通过 From 实现所有权 |
| 中间件 | Tower 层 | 基于 Trait 的组合 |
相关技能
| 场景 | 参阅 |
|---|---|
| 异步模式 | m07-concurrency |
| 状态管理 | m02-resource |
| 错误处理 | m06-error-handling |
| 中间件设计 | m12-lifecycle |
评论
支持 Markdown