Por qué separar en capas
Si metes el acceso a datos, la validación y la lógica HTTP en una sola función, acabas con código imposible de probar y de mantener. Una API limpia separa responsabilidades en capas, cada una con un trabajo:
Petición HTTP
│
▼
[ middleware ] ── auth (¿quién eres?) y validación (¿datos correctos?)
│
▼
[ controlador/handler ] ── traduce HTTP ↔ datos: lee req, responde res
│
▼
[ repositorio ] ── lee y escribe el almacén (aquí, un array en memoria)
El repositorio (acceso a datos)
Funciones JavaScript puras que operan sobre el almacén. No saben nada de HTTP:
function crear(tareas, titulo) {
const tarea = { id: tareas.length + 1, titulo, hecha: false };
tareas.push(tarea);
return tarea;
}
function buscarPorId(tareas, id) {
return tareas.find((t) => t.id === id);
}
Los middleware (auth y validación)
Se ejecutan antes del handler. Si algo va mal, responden y cortan la
cadena; si todo está bien, llaman a next():
function requiereAuth(req, res, next) {
if (!req.headers.authorization) {
res.status(401).json({ error: "No autorizado" });
return;
}
next();
}
El handler (controlador)
Es el único que toca req y res: lee la entrada, llama al repositorio y
elige el código de estado y el cuerpo de la respuesta:
function crearTarea(req, res) {
const tarea = crear(tareas, req.body.titulo);
res.status(201).json(tarea);
}
En este módulo construirás cada pieza por separado y comprobarás que funciona de forma aislada. Así es como se ensambla una API que escala.