Back to list
zzoohub

axum

by zzoohub

diet-diary & sharing app made with react-native

0🍴 0📅 Jan 23, 2026

SKILL.md


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 # Transaction, testing, error handling patterns

Axum + SQLx

For latest axum APIs, use context7. For latest sqlx APIs, use context7.

Project Structure

src/
├── main.rs
├── config.rs
├── db.rs                # Pool setup
├── error.rs             # AppError + IntoResponse
└── features/
    └── users/
        ├── mod.rs
        ├── router.rs
        ├── handlers.rs
        ├── models.rs
        └── service.rs
migrations/
.sqlx/                   # Offline cache (COMMIT THIS)

Critical Patterns

State (Don't Double-Arc)

// PgPool is Arc internally - NEVER wrap again
#[derive(Clone)]
pub struct AppState {
    pub db: PgPool,  // ✅ Direct
    // pub db: Arc<PgPool>,  // ❌ Double Arc
}

Rule: PgPool is already Arc. Wrapping again wastes memory.

Route Syntax (Axum 0.8+)

// ❌ Old syntax (0.7 and below)
.route("/users/:id", get(get_user))

// ✅ New syntax (0.8+)
.route("/users/{id}", get(get_user))

Rule: Axum 0.8 uses {id}, not :id.

Transaction Dereference

let mut tx = state.db.begin().await?;

// ❌ Won't compile
sqlx::query!(...).fetch_one(tx).await?;

// ✅ Dereference with &mut *tx
sqlx::query!(...).fetch_one(&mut *tx).await?;

tx.commit().await?;

Rule: Always use &mut *tx when passing transaction to queries.

Query Method Selection

MethodReturnsUse when
fetch_oneRow or RowNotFoundRow MUST exist
fetch_optionalOption<Row>Row might not exist
fetch_allVec<Row> (empty ok)List
// ❌ Errors if user doesn't exist
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
    .fetch_one(&state.db)
    .await?;

// ✅ Handle missing gracefully
let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
    .fetch_optional(&state.db)
    .await?
    .ok_or(AppError::NotFound)?;

Rule: Use fetch_optional for lookups. fetch_one only when row must exist.


SQLx Type Mapping

PostgresRustRequired Feature
UUIDuuid::Uuidsqlx/uuid
TIMESTAMPTZchrono::DateTime<Utc>sqlx/chrono
JSONBserde_json::Valuesqlx/json
BIGINTi64-
Nullable columnOption<T>-

Rule: Nullable column must be Option<T>. Mismatch = runtime panic.


Offline Mode (CI/CD)

# 1. Generate cache locally (requires DATABASE_URL)
cargo sqlx prepare

# 2. Commit .sqlx/ directory
git add .sqlx/

# 3. In CI (no database needed)
SQLX_OFFLINE=true cargo build

Rule: Always commit .sqlx/. Run cargo sqlx prepare before pushing.


Common Gotchas

ProblemCauseFix
Pool timeoutConnections exhaustedAdd acquire_timeout, check long txns
Compile error (no DB)DATABASE_URL missingcargo sqlx prepare + SQLX_OFFLINE=true
RowNotFoundfetch_one on missingUse fetch_optional
Checksum errorMigration modifiedNever modify applied migrations
Type mismatch panicNullable without OptionMatch nullability exactly

Pool Configuration

PgPoolOptions::new()
    .max_connections(10)
    .acquire_timeout(Duration::from_secs(3))  // Fail fast
    .idle_timeout(Duration::from_secs(600))
    .connect(database_url)
    .await?

Rule: Always set acquire_timeout. Silent hangs are worse than errors.


Quick Checklist

Syntax

  • {id} for path params (not :id)
  • &mut *tx for transactions

SQLx

  • fetch_optional for lookups
  • Nullable columns are Option<T>
  • .sqlx/ committed
  • cargo sqlx prepare before CI

Pool

  • No double Arc on PgPool
  • acquire_timeout set
  • Don't hold transactions long

Errors

  • AppError implements IntoResponse
  • Map sqlx::Error to proper HTTP status

Security Configuration

ItemValue
Password hashingargon2id (64MB memory) or bcrypt 12 rounds
JWT access token1 hour
JWT refresh token (web)90 days
JWT refresh token (mobile)1 year
JWT algorithmHS256
CORSExplicit origins only

Score

Total Score

40/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon