关于 axum-code-review
axum-code-review 是用于审查 Axum 应用的 Rust 代码审查技能,面向 Rust 开发者。它按版本和 edition 提供检查清单,并要求报告问题前核验证据。
主要功能
- 01按版本和 edition 审查
- 02路由与提取器检查
- 03状态管理与错误处理检查
- 04中间件审查清单
- 05证据与严重性门槛
适用场景
- 01审查 Axum 路由和处理器变更
- 02检查提取器顺序与共享状态
- 03评估中间件和错误响应
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ existential-birds/ beagle --skill axum-code-review安装后在 Claude Code 中输入/axum-code-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/extractors.mdmiddleware.mdrouting.md详细介绍
Axum 代码审查
审查工作流
- 检查 Cargo.toml — 记录 axum 版本(0.6 与 0.7+ 的模式不同)、Rust edition(2021 与 2024)、tower、tower-http 功能。Edition 2024 会改变处理器返回类型中的 RPIT 生命周期捕获方式,并且自定义提取器不再需要
async-trait。 - 检查路由 — 路由组织、方法路由、嵌套路由器
- 检查提取器 — 顺序很重要(请求体提取器必须放在最后),类型是否正确
- 检查状态 — 通过
State<T>共享状态,而不是使用全局可变状态 - 检查错误处理 —
IntoResponse实现、错误类型
报告发现前的关卡
按顺序运行。在适用步骤通过前,不要编写发现项。
-
磁盘上的版本和 edition — 通过条件: 已读取相关的
Cargo.toml(crate 或工作区根目录),并能说明axum(以及相关的 tower/tower-http)版本和 Rustedition。然后仅在该文件支持时,才应用 0.6 与 0.7+ 或 Edition 2024 专属的检查清单项。 -
每项发现的证据 — 通过条件: 每个问题都引用当前代码树中相关处理器、路由器、中间件层或类型的
[FILE:LINE](不能依赖记忆、仅查阅文档或其他分支)。 -
根据协议检查类别 — 通过条件: 针对发现类型(路由冲突、提取器顺序、错误泄露、中间件顺序等),运行 review-verification-protocol 技能中对应的检查(例如,检查提取器顺序时查看完整的处理器签名;指出“向客户端返回原始错误”前检查相关的错误映射)。然后添加发现项。
-
输出格式 — 通过条件: 报告行符合下方的输出格式(严重程度 + 描述)。
输出格式
按以下格式报告发现项:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
快速参考
| 问题类型 | 参考 |
|---|---|
| 路由定义、嵌套、方法路由 | references/routing.md |
| 状态、Path、Query、Json、请求体提取器 | references/extractors.md |
| Tower 中间件、中间件层、错误处理 | references/middleware.md |
审查清单
路由
- 按领域组织路由(为
/api/users、/api/orders使用嵌套路由器) - 为 404 定义回退处理器
- 明确指定方法路由(使用
.get()、.post(),而不是使用.route()手动匹配方法) - 没有路由冲突(不同提取器使用重叠路径)
提取器
- 消耗请求体的提取器(
Json、Form、Bytes)是最后一个参数 -
State<T>要求T: Clone— 通常使用Arc<AppState>或直接派生Clone -
Path<T>参数类型与路由定义一致 - 对于可选查询参数,
Query<T>字段使用Option,并添加#[serde(default)] - 自定义提取器实现
FromRequestParts(不处理请求体)或FromRequest(处理请求体) - Edition 2024:自定义提取器在 trait 实现中使用原生
async fn(FromRequest/FromRequestParts不需要#[async_trait])
状态管理
- 通过
State<T>共享应用程序状态,而不是使用全局可变静态变量 - 数据库连接池存放在状态中(而不是每次请求都创建)
- 状态仅包含共享资源(连接池、配置、通道),不包含请求专属数据
- 状态类型派生
Clone或手动实现该 trait - Edition 2024:共享静态状态使用标准库中的
LazyLock(而不是once_cell::sync::Lazy或lazy_static!)
错误处理
- 处理器错误实现
IntoResponse,以返回正确的 HTTP 错误代码 - 内部错误不会泄露给客户端(500 响应中不包含原始错误消息)
- 错误响应使用一致的格式(包含 code/message 的 JSON 错误主体)
- 处理器使用
Result<impl IntoResponse, AppError>模式 - Edition 2024:处理器返回类型
-> impl IntoResponse默认会捕获作用域内的所有生命周期;返回自有数据时,使用+ use<>可选择不捕获请求生命周期
中间件
- Tower 层按正确顺序应用(请求时最外层先运行,响应时最后运行)
- 对于常见关注点(CORS、压缩、追踪、超时)使用
tower-http - 通过扩展传递请求作用域数据,而非使用全局状态
- 中间件错误不会触发 panic,而是返回错误响应
- Edition 2024:使用
#[async_trait]的中间件可迁移为 trait 实现中的原生async fn
严重程度分级
严重
- 处理器参数中的 Body 提取器不是最后一个(会静默消耗请求主体,导致后续提取器失败)
- 通过路径/查询参数直接传入查询,造成 SQL 注入
- 内部错误详情泄露给客户端(堆栈跟踪、数据库错误)
- 受保护路由缺少身份验证中间件
主要
- 使用全局可变状态,而非
State<T>(会产生竞态条件) - 缺少错误类型转换(将原始
sqlx::Error返回给客户端) - 缺少请求超时(处理器可能无限期挂起)
- 路由冲突导致意外的 405 响应
- Edition 2024:在原生 async fn 可用时,
FromRequest/FromRequestParts仍使用async-trait
次要
- 使用手动路由方法匹配,而非
.get()、.post() - 缺少回退处理器(默认 404 是纯文本,而非 JSON)
- 中间件按路由应用,但实际应全局应用(反之亦然)
- 缺少
tower-http::trace进行请求日志记录 - Edition 2024:在
std::sync::LazyLock可用时仍使用once_cell::sync::Lazy或lazy_static!
提示
- 建议使用
tower-http层处理常见关注点 - 路由组织方面的改进
- 建议通过
utoipa或aide添加 OpenAPI 文档
有效模式(不要标记)
- 在处理器上使用
#[axum::debug_handler]— 可改善编译错误消息的调试辅助功能 - 使用
Extension<T>注入中间件数据 — 适用于请求作用域值的有效模式 - 处理器返回
impl IntoResponse— 比具体类型更灵活 - 每个模块使用
Router::new(),并在主模块中合并 — 标准组织模式 - 使用
ServiceBuilder组合层 — Tower 模式,并非过度设计 - 使用
TcpListener配合axum::serve— axum 0.7+ 的标准服务器设置方式 - 在
FromRequest/FromRequestParts实现中使用原生async fn— 不再需要async-traitcrate(自 Rust 1.75 起稳定) - 在处理器返回类型中使用
+ use<'a>— Edition 2024 中用于 RPIT 的精确捕获语法 - 使用
std::sync::LazyLock管理共享静态状态 — 替代once_cell/lazy_static(自 Rust 1.80 起稳定)
提交发现前
在将任何问题定为最终结果之前,请完成 Gates(报告发现前),并加载 review-verification-protocol 技能,以进行特定类别的检查。
评论
支持 Markdown