El módulo 3 terminó con una frase honesta: todavía no existe el código de un servicio completo. Antes de escribirlo hay que tomar una decisión que condiciona todo lo demás: con qué se construyen los servicios de TechCorp. En un monolito esta decisión se toma una vez y para siempre; en microservicios se puede tomar por servicio, y esa libertad es a la vez la mayor ventaja y la mayor fuente de caos. En esta lección fijamos los criterios de elección, recorremos el panorama de tecnologías por categoría, tomamos las decisiones concretas de TechCorp (con la regla de Marta de las dos bases de datos como ejemplo de "libertad con límites") y preparamos el terreno práctico: la plantilla de servicio, la librería @techcorp/comun-http, las herramientas de desarrollo local y la organización de los repositorios. Todo lo que se decide aquí lo usaremos, tal cual, en las cuatro lecciones siguientes.

Contenido

  1. Criterios de elección para un microservicio
  2. Lenguajes y frameworks
  3. Bases de datos y caché
  4. Brokers de mensajes, configuración, contenedores, CI/CD, observabilidad y pruebas
  5. Heterogeneidad con criterio: políglota, pero con lista corta
  6. La plantilla de servicio y la librería @techcorp/comun-http
  7. Herramientas de desarrollo local
  8. Monorepo o multirepo: la organización del código

  1. Criterios de elección para un microservicio

Elegir tecnología para un microservicio no es lo mismo que elegirla para una aplicación monolítica. Un monolito arranca una vez al día y ocupa un servidor; un microservicio se replica, se reinicia con frecuencia (despliegues, autoescalado, reprogramación de pods) y convive con docenas de vecinos en el mismo clúster. Eso cambia el peso de cada criterio:

Criterio Qué mide Por qué pesa más en microservicios
Madurez y ecosistema Años de uso en producción, librerías para HTTP, BD, AMQP, OpenTelemetry, pruebas Cada servicio necesita todas las piezas de la lista; una laguna se multiplica por el número de servicios
Conocimiento del equipo Cuántas personas pueden escribir, revisar y operar código en esa tecnología Con ~25 técnicos, un servicio en un lenguaje que solo conoce una persona es un riesgo de continuidad
Rendimiento Peticiones por segundo por réplica, latencia p99 Importa, pero menos de lo que se cree: 3.000 pedidos/día no exigen Go; los picos ×20 (01-05) tampoco
Tiempo de arranque Segundos desde docker run hasta /health/ready Con rolling updates y autoescalado (05-04, 06-04) un arranque de 40 s retrasa cada despliegue y cada escalado
Consumo de memoria MB en reposo por réplica Diez servicios × tres réplicas × 512 MB es un nodo entero; en Kubernetes la memoria se paga por réplica
Soporte de contenedores Tamaño de imagen, imágenes oficiales, comportamiento ante SIGTERM Un proceso que ignora SIGTERM pierde peticiones en cada despliegue (lo veremos en 04-02)
Observabilidad Instrumentación de logs estructurados, métricas Prometheus y trazas OpenTelemetry disponible y estable Sin ella, depurar un flujo que cruza cinco servicios (módulo 6) es imposible
Velocidad de desarrollo Cuánto cuesta un endpoint nuevo, un consumidor nuevo En la migración incremental (01-05) se van a crear siete servicios en pocos meses

Un consejo de método: puntuad los criterios antes de mirar tecnologías. Si el equipo primero elige la tecnología que le gusta y luego busca criterios que la justifiquen, la tabla no sirve para nada.

  1. Lenguajes y frameworks

Panorama de las opciones habituales para servicios HTTP + eventos (valores orientativos para un servicio pequeño con un endpoint y un consumidor):

Tecnología Arranque Memoria en reposo Rendimiento Ecosistema microservicios Curva para el equipo de TechCorp
Node.js 20 + Express < 1 s ~40-60 MB Medio-alto (E/S asíncrona) Excelente: pg, mongodb, amqplib, pino, OpenTelemetry, Jest Ninguna: es el lenguaje del monolito
Node.js + Fastify < 1 s ~40-60 MB Alto (2-3× Express en benchmarks) Excelente; validación JSON Schema integrada Baja: mismo lenguaje, API distinta
Node.js + NestJS 1-2 s ~70-100 MB Medio-alto Muy bueno; opinado (módulos, DI, decoradores) Media: TypeScript + estructura propia
Java + Spring Boot 5-15 s ~250-400 MB Alto El más completo (Spring Cloud) Alta: nadie en TechCorp programa Java
Java + Quarkus / Micronaut < 1 s (nativo) / 2-3 s (JVM) ~50-150 MB Alto Muy bueno; diseñado para contenedores Alta
Go (net/http, Gin, Echo) < 100 ms ~10-20 MB Muy alto Bueno; binario único, imágenes de 10-20 MB Media-alta: dos personas de Plataforma lo conocen
Python + FastAPI 1-2 s ~50-80 MB Medio Bueno; tipado con Pydantic, OpenAPI automático Media: lo usa el equipo de datos
.NET 8 (Minimal APIs) 1-2 s ~60-100 MB Alto Muy bueno Alta: sin experiencia en la empresa

Lecturas de la tabla:

  • No hay una opción "correcta": Spring Boot es una elección excelente en una empresa Java, y pésima en TechCorp, donde nadie lo conoce y el arranque de 10 s complicaría el autoescalado.
  • Node.js y Go son los dos extremos habituales de "ligero": Node por productividad y ecosistema, Go por consumo y rendimiento. Muchas empresas usan ambos: Node para servicios de negocio, Go para piezas de infraestructura o alto tráfico.
  • Express frente a Fastify frente a NestJS es una decisión menor comparada con la de lenguaje. Express es el más conocido y el que ya usa el monolito; Fastify es más rápido y trae validación; NestJS impone estructura (útil en equipos grandes, un peso en equipos pequeños). Como el rendimiento no es el cuello de botella de TechCorp y el monolito ya es Express, el coste de cambiar no compensa hoy.

Decisión de TechCorp (Marta y los cuatro equipos, reunión de arquitectura): Node.js 20 LTS + Express en JavaScript para todos los servicios de la primera oleada. Se deja escrito que Go es la segunda tecnología aprobada para servicios con requisitos de rendimiento o consumo (candidato: un futuro servicio de búsqueda del catálogo), y que TypeScript se valorará cuando el primer servicio esté en producción. La justificación en una frase: "el riesgo del proyecto está en la arquitectura distribuida, no en el lenguaje; no sumemos una segunda curva de aprendizaje".

  1. Bases de datos y caché

Aquí el módulo 2 ya hizo el trabajo pesado (02-04): base de datos por servicio, PostgreSQL para pedidos, clientes, pagos e inventario; MongoDB para el catálogo. Lo que añade esta lección es el criterio general y el papel de la caché:

Tecnología Modelo Cuándo elegirla en un microservicio Cuándo no
PostgreSQL Relacional, transacciones ACID, JSONB Agregados con invariantes (Pedido, Reserva, Pago), necesidad de transacción local (outbox, eventos_procesados), consultas con filtros combinados Documentos con estructura muy variable y sin relaciones (se puede, con JSONB, pero MongoDB es más natural)
MongoDB Documental, esquema flexible Documentos autocontenidos y heterogéneos (fichas de producto con atributos distintos por categoría), lectura por id o por pocos índices Transacciones entre colecciones frecuentes, invariantes fuertes (existen transacciones multi-documento, pero es señal de que el modelo no es documental)
Redis Clave-valor en memoria, TTL, estructuras (listas, sets, sorted sets) Caché de lecturas costosas (respuesta de GET /v1/productos?ids=), contadores, rate limiting del gateway (03-04), sesiones Como base de datos principal de un agregado de negocio: es memoria; la persistencia es opcional y las garantías, distintas
Otras (Cassandra, DynamoDB, Elasticsearch...) Columnar, clave-valor gestionada, búsqueda Volúmenes o casos de uso específicos (búsqueda de texto libre, series temporales) Antes de tener el problema que resuelven

Sobre Redis conviene una precisión: la caché no es una base de datos más a efectos de la regla de Marta ("máximo dos tecnologías de base de datos", 02-04) porque no guarda la verdad de ningún agregado; si Redis se vacía, el sistema sigue funcionando más lento. Aun así, TechCorp no lo introduce todavía: Cache-Control: max-age=30 en Catálogo (03-01) cubre la necesidad actual. Se apunta como candidato para 06-04 (rendimiento).

  1. Brokers de mensajes, configuración, contenedores, CI/CD, observabilidad y pruebas

El resto de categorías del stack ya tiene lección propia en este curso; aquí solo el mapa y la decisión, para que veas el conjunto de una vez.

Brokers de mensajes (detalle en 03-02):

Broker Modelo Fortaleza Cuándo elegirlo
RabbitMQ Colas AMQP, exchanges, enrutamiento flexible, DLQ nativa Semántica de cola clara, herramientas maduras, fácil de operar a escala media Eventos de negocio y comandos, volúmenes de miles a cientos de miles de mensajes/día
Apache Kafka Log particionado y persistente, consumidores que releen Volumen masivo, replay, streaming Millones de eventos/día, analítica en tiempo real, event sourcing
NATS / JetStream Muy ligero, pub-sub, colas con JetStream Latencia mínima, operación sencilla Comunicación interna en clústeres grandes, IoT

Decisión: RabbitMQ, ya tomada en 03-02, por volumen (3.000 pedidos/día), por la DLQ nativa y por la topología de colas por consumidor que definimos.

Gestión de configuración (detalle en 04-03): variables de entorno como interfaz universal; ConfigMaps y Secrets de Kubernetes como fuente en producción; Consul KV / Vault / Spring Cloud Config como opciones centralizadas cuando hay decenas de servicios con configuración compartida. TechCorp: variables de entorno, punto.

Contenedores y orquestación (módulo 5): Docker para construir imágenes; Kubernetes para ejecutarlas en producción; alternativas como Nomad, ECS o Cloud Run tienen sentido en contextos concretos. TechCorp: Docker + Kubernetes; en local, Docker Compose. Todo servicio de este módulo se contenerizará en 05-01, y por eso lo escribimos desde el principio para que arranque rápido, lea su configuración del entorno y muera limpiamente con SIGTERM.

CI/CD (05-03): GitHub Actions (el código de TechCorp está en GitHub), GitLab CI y Jenkins son equivalentes en capacidad; la elección la dicta dónde vive el código.

Observabilidad (módulo 6): logs con pino en JSON → Loki; métricas con prom-client → Prometheus + Grafana; trazas con OpenTelemetry → Jaeger. La alternativa clásica es ELK (Elasticsearch, Logstash, Kibana). En este módulo solo usaremos pino como logger mínimo.

Pruebas (04-05): Jest o Vitest como runner, Supertest para probar Express sin abrir puerto, Testcontainers para levantar PostgreSQL/RabbitMQ reales en las pruebas de integración, Pact para contratos entre consumidor y proveedor.

  1. Heterogeneidad con criterio: políglota, pero con lista corta

Uno de los argumentos de venta de los microservicios (01-02) es la libertad tecnológica: cada equipo elige lo mejor para su problema. La experiencia dice que esa libertad, sin límites, produce lo siguiente en dos años: siete lenguajes, cuatro bases de datos, dos brokers, y un servicio crítico en Elixir que nadie sabe tocar porque quien lo escribió se fue. El coste no está en escribir, sino en operar: cada tecnología necesita imágenes base, plantillas de CI, dashboards, alertas, guías de seguridad y personas de guardia que la entiendan.

La respuesta madura no es prohibir la heterogeneidad, sino gobernarla:

flowchart LR
    A[Equipo quiere usar<br/>tecnología X] --> B{¿Está en la<br/>lista aprobada?}
    B -- Sí --> C[Adelante: plantilla,<br/>CI y observabilidad ya existen]
    B -- No --> D{¿Resuelve un problema<br/>que la lista no resuelve?}
    D -- No --> E[Se usa la aprobada]
    D -- Sí --> F[Propuesta al comité<br/>de arquitectura: piloto acotado]
    F --> G{¿El piloto justifica<br/>el coste operativo?}
    G -- Sí --> H[Entra en la lista:<br/>Plataforma crea plantilla y soporte]
    G -- No --> E

La lista corta aprobada de TechCorp, tal y como la publica el equipo de Plataforma en su repositorio:

Categoría Aprobado hoy Aprobado con justificación Fuera
Lenguaje/framework Node.js 20 LTS + Express (JavaScript) Go (alto rendimiento/consumo); TypeScript (tras el primer servicio en producción) Cualquier otro sin pasar por el comité
Base de datos PostgreSQL 16 MongoDB 7 (solo Catálogo por ahora) Una tercera tecnología: regla de Marta, máximo dos
Caché Redis (cuando 06-04 lo justifique)
Broker RabbitMQ Kafka mientras el volumen no lo exija
Contenedores Docker + Kubernetes
Observabilidad pino + Prometheus/Grafana/Loki + OpenTelemetry/Jaeger ELK en paralelo

Fíjate en el detalle de la regla de Marta: no es "PostgreSQL y nada más", es "dos tecnologías", lo que dio cabida a MongoDB donde su modelo encaja (02-04) y a la vez cierra la puerta a una tercera. Ese es el espíritu de la lista corta: libertad real dentro de un perímetro que Plataforma puede sostener.

  1. La plantilla de servicio y la librería @techcorp/comun-http

Con siete servicios en la misma tecnología, lo que se repite conviene resolverlo una vez, y hay dos mecanismos distintos para ello que no deben confundirse:

6.1 La plantilla de servicio (arquetipo)

Es un repositorio de ejemplo (techcorp/plantilla-servicio-node) que se copia al crear un servicio nuevo. Contiene la estructura de carpetas, el package.json con las dependencias y scripts acordados, el Dockerfile (05-01), el workflow de CI (05-03), la configuración de eslint, un .env.ejemplo y un servicio de ejemplo con /health/live y /health/ready que arranca a la primera. Una plantilla se copia y luego cada servicio evoluciona por su cuenta: no hay acoplamiento, y por eso puede contener opiniones (estructura de carpetas, nombres de scripts). En 04-02 construiremos servicio-catalogo desde cero precisamente para entender lo que la plantilla daría hecho.

6.2 La librería @techcorp/comun-http

Es un paquete npm versionado, publicado en el registro privado de TechCorp, que cada servicio declara como dependencia ("@techcorp/comun-http": "^1.2.0") y actualiza cuando le conviene. Ya la hemos ido nombrando desde 02-02; ahora fijamos su contenido:

Exporta Qué hace Dónde se definió
crearLogger({ servicio }) Un logger pino en JSON con los campos comunes (servicio, nivel, hora, requestId) Aquí; formato completo en 06-01
middlewareRequestId() Lee X-Request-Id o genera uno (req-<ulid>), lo pone en req.id, en la respuesta y en el logger de la petición 03-01 (correlación)
responderProblema(res, req, problema) Formato RFC 7807 application/problem+json con codigo e instance 03-01
middlewareErrores({ logger }) Último middleware de Express: convierte excepciones en problem+json (500 genérico o el codigo de negocio) 04-02
crearRutasSalud({ comprobaciones }) /health/live y /health/ready con timeout de 1 s por dependencia y 503 en apagado 03-05
ErrorNegocio(codigo, mensaje, status) Clase base de errores de dominio (CLIENTE_NO_EXISTE, PRODUCTO_NO_DISPONIBLE...) que el middleware sabe traducir 04-02
mensajeria/topologia (conectar, declararColaConsumidor) y mensajeria/publicador (construirSobre, publicarEvento) Topología RabbitMQ y sobre estándar 03-02

Y, tan importante como lo que contiene, lo que no contiene:

  • procesarUnaVez no está en la librería. Depende de la base de datos de cada servicio (tabla eventos_procesados en PostgreSQL en Pedidos; en Catálogo, si algún día consume eventos, sería una colección de MongoDB). Meterlo en la librería obligaría a la librería a conocer pg y mongodb, y arrastraría a todos los servicios a la misma versión del driver. Cada servicio lo implementa (son 15 líneas) sobre su propia BD.
  • Ningún modelo de negocio. Ni Pedido, ni Producto, ni validaciones de negocio. Una librería con lógica de dominio compartida es el monolito distribuido de 02-01: un cambio en Pedido obligaría a redesplegar a todos.
  • Ningún cliente de otro servicio. catalogoCliente.js vive en Pedidos, no en la librería: es Pedidos quien decide qué necesita de Catálogo y con qué timeout.
  • Ninguna configuración concreta. La librería no sabe qué URL tiene Catálogo; recibe valores.

La regla para decidir: si al cambiar esta pieza tendrían que redesplegarse varios servicios a la vez, no debe estar en la librería. Todo lo que hay en @techcorp/comun-http es técnico, estable y opcional de actualizar.

  1. Herramientas de desarrollo local

Un desarrollador de TechCorp necesita poder arrancar su servicio en su portátil, con sus dependencias reales (una base de datos, RabbitMQ) y sin levantar los otros seis servicios. La caja de herramientas acordada:

Herramienta Para qué Nota
Node.js 20 LTS (vía nvm o fnm) Ejecutar los servicios; misma versión mayor que la imagen de producción .nvmrc con 20 en cada repositorio
npm Dependencias y scripts (npm run dev, npm test) Se usa npm ci en CI para respetar package-lock.json
nodemon Reiniciar el servicio al guardar un fichero en desarrollo Solo devDependencies; en producción, node src/servidor.js
Docker Desktop / Podman Levantar PostgreSQL, MongoDB y RabbitMQ locales con un docker run o un docker compose up El servicio se ejecuta con Node en el portátil; en contenedor solo las dependencias (05-01 dará el paso siguiente)
curl / HTTPie / Postman Probar endpoints a mano En este curso usamos curl para que los ejemplos sean copiables
VS Code + extensión REST Client Ficheros .http versionados junto al servicio con las peticiones de ejemplo Sustituye a colecciones de Postman fuera del repositorio
RabbitMQ Management (http://localhost:15672) Ver colas, mensajes, DLQ Viene con la imagen rabbitmq:3-management
psql / mongosh Inspeccionar datos También sirven las extensiones del IDE

Ejemplo de dependencias locales, tal y como las arrancará cada lección de este módulo (una línea cada una; el docker compose completo es de 05-01):

# MongoDB para servicio-catalogo (04-02)
docker run -d --name mongo-catalogo -p 27017:27017 mongo:7

# PostgreSQL para servicio-pedidos (04-04). Contraseña ficticia solo para desarrollo.
docker run -d --name pg-pedidos -p 5432:5432 -e POSTGRES_USER=svc_pedidos \
  -e POSTGRES_PASSWORD=dev-pedidos -e POSTGRES_DB=pedidos postgres:16

# RabbitMQ con consola de administración (04-04)
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

Con esto, la variable PEDIDOS_DB_URL de 03-05 vale en local postgres://svc_pedidos:dev-pedidos@localhost:5432/pedidos y RABBITMQ_URL vale amqp://localhost:5672. Los mismos nombres de variable, valores distintos por entorno: exactamente el mecanismo que 04-03 formalizará.

  1. Monorepo o multirepo: la organización del código

Última decisión antes de escribir código: dónde vive cada servicio.

Aspecto Monorepo (un repositorio para todo) Multirepo (un repositorio por servicio)
Cambios que tocan varios servicios Un solo commit y una sola PR Varias PR coordinadas
Autonomía de equipos Menor: permisos, CI y convenciones compartidas Máxima: cada equipo decide su CI, su ritmo, sus revisores
Despliegue independiente Posible, pero hay que evitar que un cambio en A dispare el pipeline de B (filtros por ruta) Natural: cada repositorio tiene su pipeline
Librerías compartidas Se importan por ruta; siempre en la última versión Se publican en un registro y cada servicio elige versión
Herramientas necesarias Nx, Turborepo, Bazel o similares a partir de cierto tamaño Ninguna especial; sí una plantilla para no divergir
Riesgo típico Que la comodidad de tocarlo todo a la vez recree el monolito Que se dupliquen utilidades y que las convenciones se dispersen
Ejemplos Google, Meta (con herramientas propias) La mayoría de empresas medianas

Ambos modelos funcionan; lo que importa es que la elección refuerce, y no contradiga, la arquitectura. Para TechCorp la clave es la autonomía de despliegue por equipo que definimos en 02-02, y el tamaño (siete servicios, cuatro equipos) no justifica montar Nx o Bazel.

Decisión de TechCorp:

  • Un repositorio por servicio: techcorp/servicio-catalogo, techcorp/servicio-pedidos, techcorp/servicio-inventario, etc. Cada uno con su Dockerfile, su workflow de CI y su equipo propietario.
  • Un repositorio de plataforma (techcorp/plataforma): manifiestos de Kubernetes, definición del gateway (03-04), dashboards, la plantilla de servicio y la lista corta aprobada del apartado 5.
  • Un repositorio para @techcorp/comun-http, publicado como paquete en el registro npm privado (GitHub Packages), con versionado semántico: los servicios se actualizan cuando quieren, no cuando cambia la librería.
  • Los contratos (OpenAPI y AsyncAPI de 03-06) viven en el repositorio del servicio proveedor, en contratos/, para que cambien en la misma PR que el código.

Estructura resultante, resumida:

techcorp/
├── plataforma/                # equipo Plataforma: k8s/, gateway/, plantilla-servicio-node/, tecnologias-aprobadas.md
├── comun-http/                # @techcorp/comun-http (paquete npm privado)
├── servicio-catalogo/         # equipo Experiencia de compra (04-02)
├── servicio-clientes/         # equipo Experiencia de compra
├── servicio-pedidos/          # equipo Pedidos (Luis) (04-04)
├── servicio-inventario/       # equipo Pedidos (Luis)
├── servicio-pagos/            # equipo Pagos y comunicaciones
├── servicio-notificaciones/   # equipo Pagos y comunicaciones
└── techcorp-shop/             # el monolito, que se va vaciando

Errores Comunes y Consejos

  • Elegir la tecnología por moda o por currículum. "Queremos Go porque es lo que se lleva" o "Kafka porque lo usa Netflix". Aplica la tabla del apartado 1 con los números reales de TechCorp: 3.000 pedidos/día no necesitan Kafka.
  • Confundir libertad con ausencia de reglas. La lista corta no es burocracia; es lo que permite que Plataforma dé soporte real. Escríbela, publícala y hazla evolucionar con pilotos.
  • Meter lógica de negocio en la librería compartida. Cada Pedido o Producto en @techcorp/comun-http es un hilo que vuelve a coser los servicios entre sí. Solo código técnico, estable y con versión.
  • Meter en la librería cosas que dependen de la BD (como procesarUnaVez). La librería acabaría dependiendo de pg y mongodb a la vez.
  • Copiar la plantilla y no volver a mirarla. La plantilla evoluciona (nuevo linter, nuevo campo de log). Conviene una revisión trimestral de qué mejoras aplicar a los servicios existentes, sin forzar.
  • Ejecutar en local con versiones distintas a producción. Node 18 en el portátil y Node 20 en la imagen esconde diferencias (por ejemplo, fetch nativo). .nvmrc y la misma versión mayor en todas partes.
  • Un monorepo sin herramientas o un multirepo sin plantilla. El primero recrea el monolito; el segundo produce siete formas distintas de hacer lo mismo.

Ejercicios

Ejercicio 1. El equipo de Pagos y comunicaciones propone escribir servicio-notificaciones en Python con FastAPI porque "solo envía correos y Python tiene buenas librerías de plantillas". Aplica el diagrama de flujo del apartado 5 y los criterios del apartado 1, y redacta la respuesta del comité de arquitectura en cinco líneas.

Ejercicio 2. Indica para cada una de estas piezas si debe ir en @techcorp/comun-http, en la plantilla de servicio, o en el propio servicio, y por qué: (a) la función transicionar de la máquina de estados del pedido; (b) el middleware que genera X-Request-Id; (c) el fichero .eslintrc; (d) el traductorProducto; (e) declararColaConsumidor; (f) el Dockerfile.

Ejercicio 3. Marta pregunta si, para simplificar, no sería mejor un único repositorio con todos los servicios en carpetas. Enumera dos ventajas reales que ganaría TechCorp y dos riesgos concretos para la arquitectura de 02-02, y propón una condición bajo la cual la respuesta sería "sí".

Soluciones

Solución 1. Python no está en la lista aprobada, así que la pregunta es si resuelve algo que Node no resuelve. No: Node tiene librerías de plantillas de correo equivalentes (por ejemplo nodemailer + motores de plantillas), y el problema de Notificaciones no es de rendimiento ni de consumo. El coste sería una segunda imagen base, una segunda plantilla de CI, instrumentación OpenTelemetry distinta y un servicio que solo dos personas podrían mantener. Respuesta del comité: "Se rechaza para este servicio. Notificaciones se hace en Node.js 20 + Express con la plantilla estándar. Si el equipo identifica una necesidad concreta que Node no cubra (por ejemplo, generación de PDF con una librería específica), puede proponer un piloto acotado con esa justificación."

Solución 2. (a) transicionar: en el servicio de Pedidos, es lógica de negocio del agregado; compartirla acoplaría. (b) Middleware de X-Request-Id: en la librería, es técnico, idéntico para todos y estable. (c) .eslintrc: en la plantilla; se copia y cada servicio puede ajustarlo sin afectar a nadie. (d) traductorProducto: en el servicio de Pedidos; es su ACL, expresa lo que Pedidos entiende de Catálogo. (e) declararColaConsumidor: en la librería (mensajeria/topologia), es técnico y encapsula la convención de DLQ de 03-02. (f) Dockerfile: en la plantilla; cada servicio lo copia y lo adapta (por ejemplo, Catálogo no necesita el cliente de PostgreSQL).

Solución 3. Ventajas: cambios transversales (por ejemplo, subir la versión de @techcorp/comun-http en todos los servicios) en una sola PR; una única configuración de linter, CI y revisiones. Riesgos: que un despliegue arrastre a otro (una PR que toca Pedidos e Inventario "porque ya que estamos" recrea el acoplamiento de despliegue); y que las importaciones por ruta relativa entre servicios (../servicio-catalogo/src/...) se cuelen sin que nadie las vea, rompiendo la base de datos por servicio y los contratos por la puerta de atrás. La respuesta sería "sí" si TechCorp adoptara una herramienta de monorepo (Nx/Turborepo) con pipelines filtrados por ruta y reglas de dependencia que prohíban importar entre servicios; con siete servicios y cuatro equipos, ese esfuerzo hoy no compensa.

Conclusión

Hemos convertido la libertad tecnológica de los microservicios en decisiones concretas y gobernadas: los criterios que pesan en un servicio replicado y efímero (arranque, memoria, contenedores, observabilidad, conocimiento del equipo) por encima del rendimiento bruto; el panorama por categoría; la lista corta aprobada de TechCorp (Node.js 20 + Express en todos los servicios, PostgreSQL + MongoDB bajo la regla de Marta de dos bases de datos, RabbitMQ, Docker/Kubernetes, pino/Prometheus/OpenTelemetry, Jest/Supertest/Testcontainers/Pact, con Go como segunda opción justificada); la diferencia entre la plantilla que se copia y la librería @techcorp/comun-http que se versiona (y la regla de oro: nada de negocio ni nada que dependa de la BD en la librería); las herramientas de desarrollo local; y la organización en un repositorio por servicio más el de plataforma.

Con la caja de herramientas cerrada, toca abrirla. En la siguiente lección construimos desde cero servicio-catalogo, el primer servicio que se extrae del monolito: npm init, la estructura por capas, la separación entre app y servidor, los endpoints GET /v1/productos del contrato de 03-01 con MongoDB detrás, el manejo de errores RFC 7807, la salud y el apagado ordenado, hasta tenerlo respondiendo a curl en el puerto 3001.

Curso de Microservicios

Módulo 1: Introducción a los Microservicios

Módulo 2: Diseño de Microservicios

Módulo 3: Comunicación entre Microservicios

Módulo 4: Implementación de Microservicios

Módulo 5: Despliegue y Orquestación

Módulo 6: Monitoreo y Mantenimiento

Módulo 7: Seguridad en Microservicios

Módulo 8: Casos de Estudio y Ejemplos Prácticos

© Copyright 2026. Todos los derechos reservados