Build Rust HTTP services with explicit state, typed boundaries, observable behavior, and production-grade runtime contracts.
Operating Model
- Read the existing service shape first: router setup, app state, middleware layers, config, database access, tests, deployment scripts, and observability.
- Prefer
axumplustowerlayers for new HTTP services unless the repo already standardizes on another framework. - Keep handlers thin. Extract inputs, call domain/service code, map results into HTTP responses.
- Make app state explicit and clone-cheap. Avoid hidden globals and ad hoc connection creation per request.
- Treat errors, tracing, timeouts, request size limits, and shutdown as part of the feature, not afterthoughts.
Reference Map
references/axum-tower-architecture.mdfor router structure, state, extractors, middleware, errors, and versioned APIs.references/runtime-config-data.mdfor Tokio runtime concerns, config, database access, background jobs, and graceful shutdown.references/testing-observability.mdfor integration tests, tracing, metrics, contract tests, and production readiness.
Defaults
- Use
tokiowith only required features unless the repo uses full feature sets consistently. - Use
serdeDTOs at HTTP boundaries and domain types internally. - Use
thiserrorfor domain errors and typed response mapping at the HTTP edge. - Use
tracing/tracing-subscriberwith structured spans and request IDs. - Use
sqlxfor database-backed services when compile-time query checking and async pooling are useful.
Verification
For service changes:
cargo fmt --all --check
cargo test --all-targets
cargo clippy --all-targets --all-features -- -D warnings
Add integration tests for new routes, error status mapping, auth/authorization branches, config parsing, database behavior, and graceful shutdown or background work when touched.