Conceptos básicos de modularidad
7 ejemplos para empezar con la Modularidad en backends de Node.js: 5 básicos y 2 intermedios.
Busca en todas las páginas de la documentación
7 ejemplos para empezar con la Modularidad en backends de Node.js: 5 básicos y 2 intermedios.
TypeScript 5.6+, Express 5 o Fastify 5, y una carpeta src/ con al menos una ruta de API.
npm install express@5 zod
npm install -D typescript@5.6 tsxLa ruta analiza HTTP y delega.
// infrastructure/http/orders-router.ts
import express from "express";
import { createOrder } from "../../application/create-order";
export const ordersRouter = express.Router();
ordersRouter.post("/", async (req, res, next) => {
try {
const order = await createOrder(req.body);
res.status(201).json({ data: order });
} catch (err) {
next(err);
}
});createOrder no tiene importaciones de ExpressRelacionado: Casos de uso y servicios - capa de aplicación
// application/create-order.ts
import type { OrderRepository } from "../domain/ports/order-repository";
export type CreateOrderDeps = { orders: OrderRepository };
export async function createOrder(
deps: CreateOrderDeps,
input: { customerId: string; sku: string; qty: number }
) {
if (input.qty <= 0) throw new Error("INVALID_QTY");
const order = { id: crypto.randomUUID(), ...input, status: "pending" as const };
await deps.orders.save(order);
return order;
}OrderRepository en memoria// domain/ports/order-repository.ts
export type Order = {
id: string;
customerId: string;
sku: string;
qty: number;
status: "pending" | "shipped";
};
export interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}infrastructure/ implementa el puertoRelacionado: Patrón de Repositorio - dobles de prueba
Permitido:
infrastructure/http -> application -> domain
Prohibido:
domain -> express
domain -> infrastructure
application -> express Request typeno-restricted-imports codifica la regla en CIRelacionado: Mejores prácticas de modularidad - lista de verificación de cumplimiento
// main.ts
import express from "express";
import { ordersRouter } from "./infrastructure/http/orders-router";
import { PostgresOrderRepository } from "./infrastructure/postgres-order-repository";
import { createOrderHandler } from "./infrastructure/http/create-order-handler";
const orders = new PostgresOrderRepository(pool);
const app = express();
app.use(express.json());
app.use("/orders", createOrderHandler({ orders }));
app.listen(3000);main.ts conoce las clases concretasRelacionado: Patrones de inyección de dependencias - manual vs Awilix vs Nest
src/
├── modules/orders/ # módulo de características - posee las reglas de pedidos
├── modules/billing/
└── shared/
├── errors.ts # Clase base AppError
└── logger.ts # instancia de pinoshared/ no tiene reglas de negocio como el cálculo de impuestosbilling la posee y expone un servicioshared/utils.tsimport { describe, it, expect } from "node:test";
import { createOrder } from "../application/create-order";
describe("createOrder", () => {
it("guarda un pedido válido", async () => {
const saved: unknown[] = [];
const orders = { save: async (o: unknown) => { saved.push(o); }, findById: async () => null };
const result = await createOrder({ orders }, { customerId: "c1", sku: "SKU1", qty: 2 });
expect(result.status).toBe("pending");
expect(saved).toHaveLength(1);
});
});node:test se ejecuta en milisegundossupertest, sin enlace de puertoVersiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.
Revisado por Chris St. John·Última actualización: 16 jul 2026