Rust web backend
Skill fusengine/agents/plugins/rust-expert/skills/rust-web-backend
Use when building a REST/HTTP backend in Rust — axum routing, extractors, shared state, middleware, error responses, sqlx database access. Not for raw async/concurrency (rust-async-concurrency).From its SKILL.md
npx -y skills add fusengine/agents --skill rust-web-backendAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 22 stars22 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.1 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
It also names the honest alternatives — sea-orm for an ActiveRecord-style ORM, diesel for a mature but synchronous alternative needing spawn_blocking — and structured observability via tracing.
Out of scope: raw async/concurrency primitives (channels, locks, task spawning) belong to rust-async-concurrency; cross-domain crate selection belongs to rust-ecosystem-crates. </objective>
Rust Web Backend
Agent Workflow (MANDATORY)
Before building the service, spawn in parallel:
- fuse-ai-pilot:explore-codebase — detect the existing router, state, and DB layer
- fuse-ai-pilot:research-expert — verify current axum/sqlx APIs via Context7/Exa (axum 0.8 changed several APIs)
- mcp__context7__query-docs — pull exact extractor/handler signatures
After building, run fuse-ai-pilot:sniper.
The 2026 standard stack
| Layer | Crate | Why |
|---|---|---|
| Runtime | tokio | De-facto async runtime; everything targets it |
| HTTP framework | axum 0.8.x | Tower-based, extractor ergonomics, minimal magic |
| Middleware | tower / tower-http | Composable layers (trace, cors, timeout, compression) |
| Database | sqlx 0.9 | Async, query! compile-time-checked SQL, no DSL; Postgres/MySQL/SQLite |
| Observability | tracing + tracing-subscriber | Structured, async-aware spans and logs |
Honest alternatives: sea-orm (ActiveRecord-style ORM, higher-level than sqlx), diesel 2.x (mature, synchronous — needs spawn_blocking or a sync pool in async apps). Prefer sqlx for the standard stack; reach for these only when their model fits.
Critical Rules
- axum 0.8 path syntax is
/{id}, not/:id—/*restbecame/{*rest}. The oldmatchitsyntax will not compile. - Errors implement
IntoResponse— never.unwrap()in a handler. Map domain errors to a status + body via one app error type. - Share state with
State<T>, wrapped once — put the pool/config in anArc-friendly struct; extract it withState, do not use globals. sqlx::query!needsDATABASE_URLat compile time — or a committed.sqlx/offline cache (cargo sqlx prepare). Plan this before CI.- No
#[async_trait]on axum extractors — 0.8 uses RPITIT; customFromRequestPartsimpls must drop the macro.
Reference Guide
Concepts
| Topic | Reference | When to Consult |
|---|---|---|
| Architecture | architecture.md | Router, extractors, State, tower middleware layout |
| Error handling | error-handling.md | App error type + IntoResponse |
| Database | database.md | sqlx pool, query!, migrations, alternatives |
| Observability | observability.md | tracing spans, subscriber, request logging |
Templates
| Template | When to Use |
|---|---|
| rest-service.md | Complete minimal REST service (router + state + handlers + errors + tracing) |
Quick Reference
Router with the 0.8 path syntax
let app = Router::new()
.route("/users", get(list).post(create))
.route("/users/{id}", get(show)) // NOT /:id
.with_state(state);
→ See architecture.md
Compile-time-checked query
let user = sqlx::query_as!(User, "SELECT id, name FROM users WHERE id = $1", id)
.fetch_optional(&pool)
.await?;
→ See database.md
Best Practices
DO
- Keep one app error type that implements
IntoResponse. - Layer cross-cutting concerns (trace, timeout, cors) via
tower-http. - Verify queries at compile time with
query!/query_as!.
DON'T
- Use
/:idroute syntax (0.7 and earlier only). .unwrap()in handlers — return a typed error.- Reach for diesel in async code without accounting for its sync nature.
Sources (verified)
- tokio.rs/blog/2025-01-01-announcing-axum-0-8-0 — path syntax, Option extractor,
#[async_trait]removal (fetched 2026-07-05) - crates.io — axum 0.8.9, sqlx 0.9.0, tokio 1.52.3, tracing 0.1.44 (current at fetch)
What ships with it: 5 files
18.8 KB alongside SKILL.md
references/
- architecture.md3.9 KB
- database.md3.6 KB
- error-handling.md3.7 KB
- observability.md3.4 KB
- templates/rest-service.md4.2 KB