axum-code-review

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Axum Code Review

Axum代码审查

Review Workflow

审查工作流

  1. Check Cargo.toml — Note axum version (0.6 vs 0.7+ have different patterns), Rust edition (2021 vs 2024), tower, tower-http features. Edition 2024 changes RPIT lifetime capture in handler return types and removes the need for
    async-trait
    in custom extractors.
  2. Check routing — Route organization, method routing, nested routers
  3. Check extractors — Order matters (body extractors must be last), correct types
  4. Check state — Shared state via
    State<T>
    , not global mutable state
  5. Check error handling
    IntoResponse
    implementations, error types
  1. 检查Cargo.toml — 记录axum版本(0.6与0.7+的模式不同)、Rust版本(2021 vs 2024)、tower、tower-http的特性。2024版本会改变处理程序返回类型中的RPIT生命周期捕获,并且自定义提取器不再需要
    async-trait
  2. 检查路由 — 路由组织、方法路由、嵌套路由
  3. 检查提取器 — 顺序很重要(体提取器必须放在最后)、类型正确
  4. 检查状态 — 通过
    State<T>
    共享状态,而非全局可变状态
  5. 检查错误处理
    IntoResponse
    实现、错误类型

Output Format

输出格式

Report findings as:
text
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
报告结果格式如下:
text
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.

Quick Reference

快速参考

Issue TypeReference
Route definitions, nesting, method routingreferences/routing.md
State, Path, Query, Json, body extractorsreferences/extractors.md
Tower middleware, layers, error handlingreferences/middleware.md
问题类型参考文档
路由定义、嵌套、方法路由references/routing.md
State、Path、Query、Json、体提取器references/extractors.md
Tower中间件、层、错误处理references/middleware.md

Review Checklist

审查清单

Routing

路由

  • Routes organized by domain (nested routers for
    /api/users
    ,
    /api/orders
    )
  • Fallback handlers defined for 404s
  • Method routing explicit (
    .get()
    ,
    .post()
    , not
    .route()
    with manual method matching)
  • No route conflicts (overlapping paths with different extractors)
  • 路由按领域组织(为
    /api/users
    /api/orders
    使用嵌套路由)
  • 定义了404的回退处理程序
  • 方法路由明确(使用
    .get()
    .post()
    ,而非手动匹配方法的
    .route()
  • 无路由冲突(不同提取器的路径重叠)

Extractors

提取器

  • Body-consuming extractors (
    Json
    ,
    Form
    ,
    Bytes
    ) are the LAST parameter
  • State<T>
    requires
    T: Clone
    — typically
    Arc<AppState>
    or direct
    Clone
    derive
  • Path<T>
    parameter types match the route definition
  • Query<T>
    fields are
    Option
    for optional query params with
    #[serde(default)]
  • Custom extractors implement
    FromRequestParts
    (not body) or
    FromRequest
    (body)
  • Edition 2024: Custom extractors use native
    async fn
    in trait impls (no
    #[async_trait]
    needed for
    FromRequest
    /
    FromRequestParts
    )
  • 消费体的提取器(
    Json
    Form
    Bytes
    )是最后一个参数
  • State<T>
    要求
    T: Clone
    — 通常是
    Arc<AppState>
    或直接派生
    Clone
  • Path<T>
    参数类型与路由定义匹配
  • Query<T>
    的可选查询参数字段使用
    Option
    并配合
    #[serde(default)]
  • 自定义提取器实现
    FromRequestParts
    (非体)或
    FromRequest
    (体)
  • 2024版本:自定义提取器在 trait 实现中使用原生
    async fn
    FromRequest
    /
    FromRequestParts
    不再需要
    #[async_trait]

State Management

状态管理

  • Application state shared via
    State<T>
    , not global mutable statics
  • Database pool in state (not created per-request)
  • State contains only shared resources (pool, config, channels), not request-specific data
  • Clone
    derived or manually implemented on state type
  • Edition 2024: Shared static state uses
    LazyLock
    from std (not
    once_cell::sync::Lazy
    or
    lazy_static!
    )
  • 应用状态通过
    State<T>
    共享,而非全局可变静态变量
  • 数据库连接池在状态中(而非每次请求创建)
  • 状态仅包含共享资源(连接池、配置、通道),不包含请求特定数据
  • 状态类型派生或手动实现了
    Clone
  • 2024版本:共享静态状态使用标准库的
    LazyLock
    (而非
    once_cell::sync::Lazy
    lazy_static!

Error Handling

错误处理

  • Handler errors implement
    IntoResponse
    for proper HTTP error codes
  • Internal errors don't leak to clients (no raw error messages in 500 responses)
  • Error responses use consistent format (JSON error body with code/message)
  • Result<impl IntoResponse, AppError>
    pattern used for handlers
  • Edition 2024: Handler return types
    -> impl IntoResponse
    capture all in-scope lifetimes by default; use
    + use<>
    to opt out of capturing request lifetimes when returning owned data
  • 处理程序错误实现
    IntoResponse
    以返回正确的HTTP错误码
  • 内部错误不泄露给客户端(500响应中不包含原始错误信息)
  • 错误响应使用统一格式(包含代码/消息的JSON错误体)
  • 处理程序使用
    Result<impl IntoResponse, AppError>
    模式
  • 2024版本:处理程序返回类型
    -> impl IntoResponse
    默认捕获所有作用域内的生命周期;当返回自有数据时,使用
    + use<>
    选择不捕获请求生命周期

Middleware

中间件

  • Tower layers applied in correct order (outer runs first on request, last on response)
  • tower-http
    used for common concerns (CORS, compression, tracing, timeout)
  • Request-scoped data passed via extensions, not global state
  • Middleware errors don't panic — they return error responses
  • Edition 2024: Middleware using
    #[async_trait]
    can migrate to native
    async fn
    in trait impls
  • Tower层按正确顺序应用(外层在请求时先执行,响应时最后执行)
  • 使用
    tower-http
    处理通用需求(CORS、压缩、追踪、超时)
  • 请求范围的数据通过扩展传递,而非全局状态
  • 中间件错误不触发panic — 而是返回错误响应
  • 2024版本:使用
    #[async_trait]
    的中间件可以迁移到 trait 实现中的原生
    async fn

Severity Calibration

严重程度校准

Critical

关键

  • Body extractor not last in handler parameters (silently consumes body, later extractors fail)
  • SQL injection via path/query parameters passed directly to queries
  • Internal error details leaked to clients (stack traces, database errors)
  • Missing authentication middleware on protected routes
  • 体提取器未放在处理程序参数的最后(会静默消费体,后续提取器会失败)
  • 通过路径/查询参数直接传递给查询导致SQL注入
  • 内部错误细节泄露给客户端(堆栈跟踪、数据库错误)
  • 受保护路由缺少认证中间件

Major

主要

  • Global mutable state instead of
    State<T>
    (race conditions)
  • Missing error type conversion (raw
    sqlx::Error
    returned to client)
  • Missing request timeout (handlers can hang indefinitely)
  • Route conflicts causing unexpected 405s
  • Edition 2024:
    async-trait
    still used for
    FromRequest
    /
    FromRequestParts
    when native async fn works
  • 使用全局可变状态而非
    State<T>
    (存在竞态条件)
  • 缺少错误类型转换(将原始
    sqlx::Error
    返回给客户端)
  • 缺少请求超时(处理程序可能无限挂起)
  • 路由冲突导致意外的405错误
  • 2024版本:在原生async fn可用的情况下,仍为
    FromRequest
    /
    FromRequestParts
    使用
    async-trait

Minor

次要

  • Manual route method matching instead of
    .get()
    ,
    .post()
  • Missing fallback handler (default 404 is plain text, not JSON)
  • Middleware applied per-route when it should be global (or vice versa)
  • Missing
    tower-http::trace
    for request logging
  • Edition 2024:
    once_cell::sync::Lazy
    or
    lazy_static!
    used where
    std::sync::LazyLock
    works
  • 使用手动路由方法匹配而非
    .get()
    .post()
  • 缺少回退处理程序(默认404是纯文本,而非JSON)
  • 中间件按路由应用,而应该全局应用(反之亦然)
  • 缺少
    tower-http::trace
    用于请求日志
  • 2024版本:在
    std::sync::LazyLock
    可用的情况下,仍使用
    once_cell::sync::Lazy
    lazy_static!

Informational

信息性

  • Suggestions to use
    tower-http
    layers for common concerns
  • Router organization improvements
  • Suggestions to add OpenAPI documentation via
    utoipa
    or
    aide
  • 建议使用
    tower-http
    层处理通用需求
  • 路由组织优化建议
  • 建议通过
    utoipa
    aide
    添加OpenAPI文档

Valid Patterns (Do NOT Flag)

有效模式(无需标记)

  • #[axum::debug_handler]
    on handlers
    — Debugging aid that improves compile error messages
  • Extension<T>
    for middleware-injected data
    — Valid pattern for request-scoped values
  • Returning
    impl IntoResponse
    from handlers
    — More flexible than concrete types
  • Router::new()
    per module, merged in main
    — Standard organization pattern
  • ServiceBuilder
    for layer composition
    — Tower pattern, not over-engineering
  • axum::serve
    with
    TcpListener
    — Standard axum 0.7+ server setup
  • Native
    async fn
    in
    FromRequest
    /
    FromRequestParts
    impls
    async-trait
    crate no longer needed (stable since Rust 1.75)
  • + use<'a>
    on handler return types
    — Edition 2024 precise capture syntax for RPIT
  • std::sync::LazyLock
    for shared static state
    — Replaces
    once_cell
    /
    lazy_static
    (stable since Rust 1.80)
  • 处理程序上的
    #[axum::debug_handler]
    — 调试辅助工具,可改善编译错误信息
  • 使用
    Extension<T>
    传递中间件注入的数据
    — 传递请求范围值的有效模式
  • 处理程序返回
    impl IntoResponse
    — 比具体类型更灵活
  • 每个模块使用
    Router::new()
    ,在主函数中合并
    — 标准组织模式
  • 使用
    ServiceBuilder
    组合层
    — Tower模式,不属于过度设计
  • 使用
    axum::serve
    配合
    TcpListener
    — axum 0.7+的标准服务器设置
  • FromRequest
    /
    FromRequestParts
    实现中的原生
    async fn
    — 不再需要
    async-trait
    crate(Rust 1.75起稳定)
  • 处理程序返回类型中的
    + use<'a>
    — 2024版本中RPIT的精确捕获语法
  • 使用
    std::sync::LazyLock
    作为共享静态状态
    — 替代
    once_cell
    /
    lazy_static
    (Rust 1.80起稳定)

Before Submitting Findings

提交结果前

Load and follow
beagle-rust:review-verification-protocol
before reporting any issue.
在报告任何问题前,请加载并遵循
beagle-rust:review-verification-protocol