Separación de controladores y servicios en Node.js
Clase 22 de 30 • Curso de Backend con ExpressJS
Resumen
Al desarrollar aplicaciones con Node.js, es clave separar claramente la lógica de negocio de la estructura de tu backend. Este enfoque facilita la escalabilidad y mantenimiento al permitir identificar rápidamente cada parte del código siempre que necesitas realizar ajustes o solucionar problemas. Para esto, es necesario dividir la aplicación en componentes claros y específicos, tales como controladores y servicios.
¿Por qué separar el controlador y el servicio en tu proyecto?
La lógica del controlador se enfoca en la recepción de datos, gestión de errores y la respuesta final al usuario, mientras que los servicios manejan estrictamente las operaciones relacionadas al negocio, como crear usuarios o manipular bases de datos.
Dividir estas responsabilidades permite:
- Identificar rápidamente dónde se encuentra un problema específico y solucionarlo sin afectar otras partes del sistema.
- Tener una estructura clara y mantenible, facilitando la incorporación de nueva lógica o funcionalidades.
¿Cómo estructurar un controlador en Node.js?
El controlador recibe datos desde una ruta, por ejemplo register
o login
, y gestiona la solicitud que hará al servicio para luego retornar una respuesta adecuada al cliente. Su estructura básica puede incluir:
- Manejo asincrónico con
async/await
. - Uso de bloques
try/catch
para gestionar errores claramente.
Por ejemplo, un controlador para registro podría verse así:
const register = async (req, res) => {
try {
const { email, password, name } = req.body;
await registerUser(email, password, name);
return res.status(201).json({ message: 'User registered successfully' });
} catch (error) {
return res.status(400).json({ error: error.message });
}
};
¿Qué implementaciones incluye un servicio en Node.js?
El servicio maneja específicamente la interacción con tu base de datos y la lógica específica del negocio. Ahí incluirás:
- El manejo seguro de contraseñas con herramientas como bcrypt.
- Creación y obtención de usuarios a través de bases de datos como Prisma.
- Generación de tokens seguros mediante JSON Web Tokens (JWT).
Por ejemplo:
const registerUser = async (email, password, name) => {
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = await prisma.user.create({
data: { email, password: hashedPassword, name, role: 'user' }
});
return newUser;
};
¿Cuáles características principales manejan los tokens JWT?
Cuando un usuario inicia sesión, es importante validar credenciales, generar tokens y manejar errores cuidadosamente para evitar dar pistas sobre la existencia o no de ciertos usuarios.
- Un usuario debería recibir un token válido que luego podrá usar para acceder a rutas seguras.
- Los errores deben manejarse genéricamente para no revelar información sensible.
La creación de tokens JWT podría verse de esta manera:
const token = jwt.sign({ id: user.id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '4h' });
¿Qué debes verificar cuando reestructuras un proyecto Node.js?
Al reorganizar tus archivos, especialmente si mueves carpetas existentes, verifica lo siguiente:
- Revisa que las nuevas rutas a los archivos sean correctas.
- Asegúrate que todas las importaciones sean adecuadas para prevenir fallas en ejecuciones.
Revisar rutas:
const authService = require('../services/authService');
Validar mediante mensajes de consola al levantar el servidor:
npm run dev
Esta comprobación rápida puede ahorrarte tiempo identificando errores simples de configuración o rutas incorrectas.
Comparte en los comentarios tu experiencia implementando esta estructura en tus proyectos con Node.js y cuéntanos cualquier duda o sugerencia que tengas sobre buenas prácticas en desarrollo backend.