Web Development
Domain Constraints
| Domain Rule |
Design Constraint |
Rust Implication |
| Stateless HTTP |
No request-local globals |
State in extractors |
| Concurrency |
Handle many connections |
Async, Send + Sync |
| Latency SLA |
Fast response |
Efficient ownership |
| Security |
Input validation |
Type-safe extractors |
| Observability |
Request tracing |
tracing + tower layers |
Critical Rules
- Web handlers must not block — block one task = block many requests. Use
spawn_blocking for CPU work.
- Shared state must be thread-safe — handlers run on any thread. Use
Arc<T>, Arc<RwLock<T>> for mutable.
- Resources live only for request duration — use extractors for proper ownership.
Framework Comparison
| Framework |
Style |
Best For |
| axum |
Functional, tower |
Modern APIs |
| actix-web |
Actor-based |
High performance |
| warp |
Filter composition |
Composable APIs |
| rocket |
Macro-driven |
Rapid development |
Key Crates
| Purpose |
Crate |
| HTTP server |
axum, actix-web |
| HTTP client |
reqwest |
| JSON |
serde_json |
| Auth/JWT |
jsonwebtoken |
| Session |
tower-sessions |
| Database |
sqlx, diesel |
| Middleware |
tower |
Design Patterns
| Pattern |
Purpose |
Implementation |
| Extractors |
Request parsing |
State(db), Json(payload) |
| Error response |
Unified errors |
impl IntoResponse |
| Middleware |
Cross-cutting |
Tower layers |
| Shared state |
App config |
Arc<AppState> |
Axum Handler Pattern
async fn handler(
State(db): State<Arc<DbPool>>,
Json(payload): Json<CreateUser>,
) -> Result<Json<User>, AppError> {
let user = db.create_user(&payload).await?;
Ok(Json(user))
}
// Error handling
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
Self::NotFound => (StatusCode::NOT_FOUND, "Not found"),
Self::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error"),
};
(status, Json(json!({"error": message}))).into_response()
}
}
Common Mistakes
| Mistake |
Domain Violation |
Fix |
| Blocking in handler |
Latency spike |
spawn_blocking |
| Rc in state |
Not Send + Sync |
Use Arc |
| No validation |
Security risk |
Type-safe extractors |
| No error response |
Bad UX |
IntoResponse impl |