Validación de entrada
La validación de entrada es un proceso fundamental que garantiza que los datos recibidos en nuestras rutas cumplan con los criterios esperados antes de ser procesados. En Express, podemos implementar validación directamente en nuestros controladores utilizando las capacidades nativas del framework y JavaScript.
Validación básica de parámetros
Express proporciona acceso directo a los datos de entrada a través de los objetos req.params
, req.query
y req.body
. La validación manual nos permite verificar estos datos antes de continuar con la lógica de negocio:
app.get('/usuarios/:id', (req, res) => {
const { id } = req.params;
// Validar que el ID sea un número
if (!id || isNaN(parseInt(id))) {
return res.status(400).json({
error: 'El ID debe ser un número válido'
});
}
// Validar rango del ID
const userId = parseInt(id);
if (userId <= 0) {
return res.status(400).json({
error: 'El ID debe ser mayor que 0'
});
}
// Continuar con la lógica
res.json({ mensaje: `Usuario ${userId} encontrado` });
});
Validación de datos del cuerpo de la petición
Para validar datos enviados en el cuerpo de las peticiones POST o PUT, podemos crear funciones de validación específicas que verifiquen la estructura y contenido:
app.post('/usuarios', (req, res) => {
const { nombre, email, edad } = req.body;
// Validar campos requeridos
if (!nombre || !email) {
return res.status(400).json({
error: 'Nombre y email son campos obligatorios'
});
}
// Validar formato de email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return res.status(400).json({
error: 'El formato del email no es válido'
});
}
// Validar edad si se proporciona
if (edad !== undefined) {
if (isNaN(parseInt(edad)) || parseInt(edad) < 0 || parseInt(edad) > 120) {
return res.status(400).json({
error: 'La edad debe ser un número entre 0 y 120'
});
}
}
// Procesar datos válidos
res.status(201).json({
mensaje: 'Usuario creado correctamente',
usuario: { nombre, email, edad }
});
});
Validación de parámetros de consulta
Los query parameters también requieren validación, especialmente cuando se utilizan para filtrado o paginación:
app.get('/productos', (req, res) => {
const { categoria, precio_min, precio_max, limite } = req.query;
// Validar categoría si se proporciona
if (categoria && typeof categoria !== 'string') {
return res.status(400).json({
error: 'La categoría debe ser una cadena de texto'
});
}
// Validar precios
if (precio_min && (isNaN(parseFloat(precio_min)) || parseFloat(precio_min) < 0)) {
return res.status(400).json({
error: 'El precio mínimo debe ser un número positivo'
});
}
if (precio_max && (isNaN(parseFloat(precio_max)) || parseFloat(precio_max) < 0)) {
return res.status(400).json({
error: 'El precio máximo debe ser un número positivo'
});
}
// Validar que precio_min no sea mayor que precio_max
if (precio_min && precio_max && parseFloat(precio_min) > parseFloat(precio_max)) {
return res.status(400).json({
error: 'El precio mínimo no puede ser mayor que el máximo'
});
}
// Validar límite de resultados
if (limite && (isNaN(parseInt(limite)) || parseInt(limite) <= 0 || parseInt(limite) > 100)) {
return res.status(400).json({
error: 'El límite debe ser un número entre 1 y 100'
});
}
res.json({ mensaje: 'Filtros válidos aplicados' });
});
Funciones auxiliares para validación
Para mantener el código organizado y reutilizable, podemos crear funciones auxiliares que encapsulen la lógica de validación común:
// Función para validar email
function validarEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
// Función para validar longitud de cadena
function validarLongitud(texto, min, max) {
if (typeof texto !== 'string') return false;
return texto.length >= min && texto.length <= max;
}
// Función para validar número en rango
function validarRango(numero, min, max) {
const num = parseFloat(numero);
return !isNaN(num) && num >= min && num <= max;
}
// Uso en las rutas
app.post('/perfil', (req, res) => {
const { nombre, email, biografia } = req.body;
if (!validarLongitud(nombre, 2, 50)) {
return res.status(400).json({
error: 'El nombre debe tener entre 2 y 50 caracteres'
});
}
if (!validarEmail(email)) {
return res.status(400).json({
error: 'Email inválido'
});
}
if (biografia && !validarLongitud(biografia, 0, 500)) {
return res.status(400).json({
error: 'La biografía no puede exceder 500 caracteres'
});
}
res.json({ mensaje: 'Perfil actualizado correctamente' });
});
Validación de tipos de datos complejos
Para estructuras de datos más complejas, podemos implementar validaciones que verifiquen arrays y objetos anidados:
app.post('/pedidos', (req, res) => {
const { cliente, productos, direccion } = req.body;
// Validar estructura del cliente
if (!cliente || typeof cliente !== 'object') {
return res.status(400).json({
error: 'Los datos del cliente son requeridos'
});
}
if (!cliente.nombre || !cliente.telefono) {
return res.status(400).json({
error: 'Nombre y teléfono del cliente son obligatorios'
});
}
// Validar array de productos
if (!Array.isArray(productos) || productos.length === 0) {
return res.status(400).json({
error: 'Debe incluir al menos un producto'
});
}
// Validar cada producto
for (let i = 0; i < productos.length; i++) {
const producto = productos[i];
if (!producto.id || !producto.cantidad || !producto.precio) {
return res.status(400).json({
error: `Producto en posición ${i + 1} tiene datos incompletos`
});
}
if (isNaN(parseInt(producto.cantidad)) || parseInt(producto.cantidad) <= 0) {
return res.status(400).json({
error: `Cantidad inválida en producto ${i + 1}`
});
}
}
res.status(201).json({ mensaje: 'Pedido creado correctamente' });
});
La validación de entrada en Express nos permite interceptar datos incorrectos antes de que lleguen a la lógica de negocio, proporcionando respuestas claras sobre los errores encontrados y manteniendo la integridad de nuestras aplicaciones.
Fuentes y referencias
Documentación oficial y recursos externos para profundizar en Express
Documentación oficial de Express
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Express es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Express
Explora más contenido relacionado con Express y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender la importancia de la validación de entrada en aplicaciones Express.
- Aprender a validar parámetros de ruta, consulta y cuerpo de las peticiones.
- Implementar funciones auxiliares para reutilizar lógica de validación.
- Validar estructuras de datos complejas como objetos anidados y arrays.
- Gestionar respuestas de error claras ante datos inválidos para mantener la integridad de la aplicación.