Request validation for actix-web.
Any type that implements the Actix FromRequest
trait can be automatically validated.
# Cargo.toml
actix-web-validation = { version = "0.0.0", features = ["validator"] }
# or
actix-web-validation = { version = "0.0.0", features = ["garde"] }
# or
actix-web-validation = { version = "0.0.0", features = ["custom"] }
use actix_web_validation::Validated;
// Do validation using your validation library
#[derive(Debug, Validate, Deserialize)]
struct Example {
#[validate(length(min = 3))]
name: String,
}
// Wrap your Actix extractor with `Validated` to automatically run validation
#[post("/")]
async fn hello(Validated(Json(payload)): Validated<Json<Example>>) -> impl Responder {
HttpResponse::Ok().body(format!("Hello {}", payload.name))
}
Custom error responses can achieved by providing an error handler.
Below is an example custom error response that responds with JSON
#[derive(Debug, Serialize, Error)]
struct CustomErrorResponse {
custom_message: String,
errors: Vec<String>,
}
impl ResponseError for CustomErrorResponse {
fn status_code(&self) -> actix_web::http::StatusCode {
actix_web::http::StatusCode::BAD_REQUEST
}
fn error_response(&self) -> HttpResponse<actix_web::body::BoxBody> {
HttpResponse::build(self.status_code()).body(serde_json::to_string(self).unwrap())
}
}
Below is an example for the validator
crate
fn error_handler(errors: ::validator::ValidationErrors, req: &HttpRequest) -> actix_web::Error {
CustomErrorResponse {
custom_message: "My custom message".to_string(),
errors: errors
.errors()
.iter()
.map(|(err, _)| err.to_string())
.collect(),
}
.into()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.validator_error_handler(Arc::new(error_handler))
// ....
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Below is an example for the garde
crate
fn error_handler(errors: ::garde::Report, req: &HttpRequest) -> actix_web::Error {
CustomErrorResponse {
custom_message: "My custom message".to_string(),
errors: errors.iter().map(|(_, err)| err.to_string()).collect(),
}
.into()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.garde_error_handler(Arc::new(error_handler))
// ....
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
This library is heavily inspired by Spring Validation and actix-web-validator.
The actix-web-validator is great but there are a few pain points I would like to address with this library.
Validated
extractor to reduce the risk of using the wrong Json
/Query
/etc extractor by mistake.Due to how Rust handles overlapping trait implementations, the actix_web_validation::Validated
can only be used when 1 feature flag is enabled. This probably won't impact most use cases because most applications will just use 1 validation library for everything. If you need to use multiple validation libraries at the same time, this library can still be used but, you will need to fully qualify the import like actix_web_validation::validator::Validated
, actix_web_validation::garde::Validated
, and actix_web_validation::custom::Validated
.