Ir al contenido
angel.library

Estructura MVC para APIs Express

src/
├── app.ts # express(): middlewares globales + montaje de rutas
├── server.ts # listen, conexión DB, shutdown limpio
├── config/ # env, constantes
├── routes/ # solo definición de endpoints → controllers
│ └── users.routes.ts
├── controllers/ # req/res: parsean entrada, llaman services, responden
│ └── users.controller.ts
├── services/ # lógica de negocio, orquestación
│ └── users.service.ts
├── repositories/ # acceso a datos (Prisma, SQL, etc.)
│ └── users.repository.ts
├── middlewares/ # auth, validación, errores, logging
├── utils/ # helpers puros
└── types/ # tipos y DTOs compartidos
Request
→ route (método + path, aplica middlewares)
→ middleware (auth, validación)
→ controller (adapta HTTP → service, nunca toca la DB)
→ service (reglas de negocio)
→ repository (consultas)
→ controller (formatea respuesta + status)
  • El controller es la única capa que conoce req/res.
  • La DB solo se toca en repositories → cambiar de ORM no rompe services.
  • Los errores se lanzan en services y los formatea un middleware de error central; no try/catch por todas partes.
middlewares/error-handler.ts
import type { ErrorRequestHandler } from "express"
export const errorHandler: ErrorRequestHandler = (err, _req, res, _next) => {
const status = err.status ?? 500
res.status(status).json({
error: status === 500 ? "Error interno" : err.message
})
}

Se registra al final, después de todas las rutas: app.use(errorHandler).