Actix-web 4 Rust ウェブフレームワークルール
actix-web 4のプロダクション向けルール: 機能別モジュール構造、型安全なエクストラクター、カスタムエラー型、非同期ベストプラクティス、ミドルウェアスタック。
# Actix-web 4 Best Practices
Actix-web 4 is the premier choice for high-performance Rust web services. Adhere to these guidelines for clean, scalable, and production-ready code. Always run `cargo fmt` and `cargo clippy` before committing.
## 1. Code Organization
Organize your codebase by feature or domain, not by generic file types.
Good structure:
```
src/
main.rs
db.rs # Database access logic
routes/ # HTTP route handlers, grouped by resource
services/ # Business logic layer
models/ # Data structures and DTOs
```
Bad: Monolithic `main.rs` or `types.rs`/`impl.rs` for everything.
## 2. Application State (`web::Data<T>`)
Use `web::Data<T>` for dependency injection and sharing application-wide state. For mutable state, wrap in `Arc<Mutex<T>>` or `Arc<RwLock<T>>` and initialize *outside* the `HttpServer::new` closure.
```rust
use actix_web::{web, App, HttpServer};
use std::sync::{Arc, Mutex};
struct AppState {
request_count: Arc<Mutex<usize>>,
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let request_count = Arc::new(Mutex::new(0)); // Initialize outside closure
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(AppState {
request_count: request_count.clone(),
}))
.route("/", web::get().to(index))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
```
## 3. Type-Safe Extractors
Leverage Actix-web's type-safe extractors (`web::Json`, `web::Path`, `web::Query`).
```rust
async fn create_user(
path: web::Path<u32>,
user_info: web::Json<UserInfo>,
) -> impl Responder {
let user_id = path.into_inner();
HttpResponse::Created().json(UserResponse { id: user_id, name: user_info.name.clone() })
}
```
## 4. Custom Error Types with `ResponseError`
Define custom error types that implement `ResponseError` for consistent, structured error responses. Use `thiserror` for ergonomic error definition.
```rust
use actix_web::{error::ResponseError, http::StatusCode, HttpResponse};
use derive_more::{Display, Error};
#[derive(Debug, Display, Error)]
pub enum AppError {
#[display(fmt = "User not found: {}", id)]
UserNotFound { id: u32, message: String },
#[display(fmt = "Database error: {}", _0)]
DbError(#[from] sqlx::Error),
}
impl ResponseError for AppError {
fn error_response(&self) -> HttpResponse {
let status = match self {
AppError::UserNotFound { .. } => StatusCode::NOT_FOUND,
AppError::DbError(_) => StatusCode::INTERNAL_SERVER_ERROR,
};
HttpResponse::build(status).json(self)
}
}
```
Do not use generic `actix_web::Error` or `panic!` in handlers.
## 5. Middleware Stack
Always include essential middleware for production readiness:
```rust
App::new()
.wrap(middleware::Logger::default()) // Request logging
.wrap(middleware::Compress::default()) // Response compression
.wrap(middleware::NormalizePath::trim()) // Trailing slash handling
.wrap(Cors::default()) // CORS
```
## 6. Blocking Operations
Actix-web is asynchronous. Use `web::block` for CPU-bound or blocking I/O operations:
```rust
async fn handle_blocking_request(body: web::Bytes) -> impl Responder {
let result = web::block(move || blocking_task(body)).await;
match result {
Ok(output) => HttpResponse::Ok().body(output),
Err(_) => HttpResponse::InternalServerError().finish(),
}
}
``` こちらもおすすめ
web-backend カテゴリの他のルール
もっとルールを探す
CLAUDE.md、.cursorrules、AGENTS.md、Image Prompts の全 223 ルールをチェック。



