Home › Rust › Rust Axum web API rules
Rust Axum web API rules
Cursor rules for Rust web services with Axum 0.8, Tokio, sqlx, typed errors, and tracing.
CursorRust
How to use
Save this as .cursor/rules/axum.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
Note: Review and test before use. Provided as is, without warranty. See Terms.
.cursor/rules/axum.mdcDownload ---
description: Rust Axum web API conventions
globs: ["src/**/*.rs","Cargo.toml"]
alwaysApply: false
---
# Rust + Axum 0.8
- Router built in `app.rs` (`fn router(state: AppState) -> Router`) so tests can call it; `main.rs` only loads config, sets up tracing, and serves with `tokio::net::TcpListener` + `axum::serve`.
- Axum 0.8 path syntax: `/users/{id}` and `/files/{*path}` (not `:id`).
- Shared state in a `#[derive(Clone)] struct AppState` (pool, config) passed with `.with_state()`; extract via `State<AppState>`.
- Handlers take extractors (`Path`, `Query`, `Json`) and return `Result<impl IntoResponse, AppError>`. `AppError` is a `thiserror` enum implementing `IntoResponse` that maps variants to status codes and hides internal details.
- No `unwrap()`/`expect()` in request paths; use `?`.
- Database with `sqlx` (`query_as!` macros checked at compile time, migrations in `migrations/` run with `sqlx migrate run`). Keep `.sqlx/` offline data updated with `cargo sqlx prepare`.
- Validate input (e.g. `validator` crate or custom `TryFrom` newtypes) before use.
- Observability: `tracing` + `tower_http::trace::TraceLayer`; add timeouts and a body size limit via `tower_http` layers.
- Don't hold a lock (`Mutex`) across `.await`; use `tokio::sync` types where needed. CPU-heavy work goes in `spawn_blocking`.
## Done when
`cargo fmt --check`, `cargo clippy --all-targets -- -D warnings`, and `cargo test` pass. Handler tests use `tower::ServiceExt::oneshot` on the router.