Validación de datos en Rust: reseña de bibliotecas y enfoques prácticos
En el desarrollo moderno con Rust, especialmente al crear servicios web y API, la validación de datos entrantes es una tarea críticamente importante. El lenguaje Rust ya proporciona un potente sistema de tipos que elimina clases enteras de errores en la etapa de compilación. Sin embargo, para verificar la lógica de negocio (por ejemplo, longitud mínima de contraseña, correo electrónico correcto, rango de números) se necesitan herramientas adicionales. En este artículo, revisaremos las tres bibliotecas más populares para la validación de datos en Rust: validator, garde y valitron.
1. Biblioteca validator
validator es, probablemente, la biblioteca más conocida y madura para la validación de estructuras en Rust. Está construida sobre atributos (derive macros) y admite muchas reglas integradas.
Instalación:
[dependencies]validator = { version = "0.18", features = ["derive"] }Ejemplo de uso:
use validator::Validate;
#[derive(Debug, Validate)]struct User { #[validate(length(min = 3, max = 20))] username: String,
#[validate(email)] email: String,
#[validate(range(min = 18, max = 120))] age: u32,
#[validate(required)] password: Option<String>,}
fn main() { let user = User { username: "Jo".to_string(), email: "invalid-email".to_string(), age: 15, password: None, };
match user.validate() { Ok(_) => println!("¡Validación superada!"), Err(errors) => { for (field, err) in &errors.errors() { println!("Error en el campo '{}': {:?}", field, err); } } }}Ventajas:
- Gran cantidad de validadores integrados: email, URL, longitud, rango, expresiones regulares.
- Soporte para funciones de validación personalizadas mediante el atributo
custom. - Buena integración con frameworks web (Actix-web, Axum, Rocket).
Desventajas:
- Depende de macros, lo que puede ralentizar la compilación.
- Los errores se devuelven como un
HashMap, lo que requiere procesamiento adicional para la API.
2. Biblioteca garde
garde es una alternativa más moderna y rápida a validator. También utiliza derive-macros, pero ofrece una API más flexible y un mejor rendimiento.
Instalación:
[dependencies]garde = "0.20"Ejemplo de uso:
use garde::Validate;
#[derive(Debug, Validate)]struct LoginRequest { #[garde(length(min = 3, max = 50))] username: String,
#[garde(ascii, length(min = 8))] password: String,
#[garde(skip)] remember_me: bool,}
fn main() { let req = LoginRequest { username: "ab".to_string(), password: "1234567".to_string(), remember_me: true, };
if let Err(errors) = req.validate() { for error in &errors { println!("Error: {} - {}", error.path(), error.message()); } } else { println!("¡Validación exitosa!"); }}Ventajas:
- Alto rendimiento gracias al código optimizado.
- Mensajes de error claros con la ruta al campo.
- Soporte para estructuras anidadas y colecciones.
- Posibilidad de crear reglas propias sin macros.
Desventajas:
- Menos validadores integrados (no tiene email, URL por defecto).
- Comunidad más pequeña que la de
validator.
3. Biblioteca valitron
valitron es una biblioteca ligera que no utiliza
También en la biblioteca
Geolocalización y mapas en Kotlin: bibliotecas, herramientas y ejemplos
tRPC para TypeScript: guía completa con ejemplos
Protocol Buffers en C++: guía completa con ejemplos prácticos
Generación de PDF en Kotlin: mejores bibliotecas y ejemplos de código
Pruebas en JavaScript (Node.js): frameworks y herramientas