AgentSkillsCN

axum

Axum 0.8+ 生产模式,搭配 SQLx。 适用场景:构建 Rust API、异步数据库、错误处理。 不适用于:API 设计决策(使用 api-design 技能)。 工作流程:api-design(设计)→ 本技能(实现)。

SKILL.md
--- frontmatter
name: axum
description: |
  Axum 0.8+ production patterns with SQLx.
  Use when: building Rust APIs, async database, error handling.
  Do not use for: API design decisions (use api-design skill).
  Workflow: api-design (design) → this skill (implementation).
references:
  - examples.md

Axum + SQLx

For latest APIs, use context7.


Core Philosophy

Axum is built on Tower - a composable middleware stack.

code
Request → [Layer₁ → Layer₂ → ... → Handler] → Response

Everything is a Service (request → response). Layers wrap services to add behavior. This enables:

  • Reusable middleware
  • Type-safe composition
  • Zero-cost abstractions
rust
// Each layer wraps the inner service, forming a pipeline
Router::new()
    .route("/users/{id}", get(get_user))
    .layer(CompressionLayer::new())   // Layer 3: outermost
    .layer(TimeoutLayer::new(...))    // Layer 2
    .layer(TraceLayer::new_for_http()) // Layer 1: innermost

Project Structure

code
src/
├── main.rs
├── lib.rs             # AppState, re-exports
├── error.rs           # AppError (RFC 9457)
├── extractors.rs      # Db, ValidatedJson
├── response.rs        # Created<T>, Ok<T>
└── features/
    └── users/
        ├── mod.rs
        ├── router.rs
        ├── handlers.rs
        └── models.rs  # Entity + repository
migrations/
.sqlx/                 # Commit this

Abstractions

Response Types

rust
async fn create(...) -> Result<Created<User>, AppError>  // 201
async fn get(...) -> Result<Ok<User>, AppError>          // 200
async fn delete(...) -> Result<NoContent, AppError>      // 204

Db Extractor

rust
async fn handler(Db(db): Db, Path(id): Path<Uuid>) -> Result<Ok<User>, AppError>

Repository

rust
User::find_or_404(&db, id).await?
User::create(&db, input).await?

Decision Guide

Query Method

SituationMethod
Must existfetch_one
May not existfetch_optional.ok_or(AppError::NotFound)
Listfetch_all

Transaction Scope

Keep transactions short. No external calls inside tx.

rust
// ✅ External call outside tx
let external = api.call().await?;
let mut tx = db.begin().await?;
// DB only
tx.commit().await?;

Pool Config

rust
PgPoolOptions::new()
    .max_connections(10)
    .acquire_timeout(Duration::from_secs(3))  // Required

Security

ItemValue
Passwordargon2id (64MB)
JWT access15-30 min
JWT refresh90 days (web), 1 year (mobile)
CORSExplicit origins

CI/CD

bash
cargo sqlx prepare
git add .sqlx/
SQLX_OFFLINE=true cargo build

Checklist

  • Response types (Created, Ok, NoContent)
  • RFC 9457 error responses
  • Db extractor
  • Repository pattern
  • Tower layers for cross-cutting concerns
  • acquire_timeout set
  • .sqlx/ committed