Definition
Imagina dos formas de coordinar una boda. En la primera, hay un wedding planner que llama al catering, luego llama a la florista, luego llama al DJ - cada instrucción depende de que el paso anterior se complete. El organizador está a cargo y conoce toda la secuencia. En el segundo enfoque, todos simplemente observan señales: cuando termina la ceremonia, el catering automáticamente empieza a servir, el DJ ve a la gente sentándose y pone música de cena, el fotógrafo nota que se está sirviendo comida y pasa a fotos espontáneas. Nadie está a cargo; cada uno simplemente conoce su señal. Eso es orquestación versus coreografía.
En la orquestación, un servicio central (el orquestador) controla explícitamente el flujo de trabajo. Conoce todos los pasos, llama a cada servicio en orden, maneja errores y gestiona el proceso general. Si necesitas cambiar el proceso, cambias el orquestador. La ventaja es la visibilidad - puedes ver todo el flujo en un solo lugar. La desventaja es el acoplamiento - ese orquestador se convierte en infraestructura crítica, y necesita conocer cada servicio que coordina.
La coreografía da la vuelta a esto. En lugar de un controlador central, los servicios se comunican a través de eventos. “¡Pedido creado!” dice el servicio de Pedidos, y no le importa quién está escuchando. El servicio de Pagos lo escucha y cobra la tarjeta, emitiendo “¡Pago completado!” El servicio de Inventario escucha eso y reserva stock. Cada servicio se ocupa de lo suyo y reacciona a eventos que le importan. Esto es más resiliente (no hay único punto de fallo) y más flexible (añadir nuevos servicios solo suscribiéndose a eventos), pero más difícil de debuggear porque el flujo es implícito, distribuido entre muchos servicios en lugar de visible en un solo lugar.
Example
Estos patrones moldean cómo los sistemas modernos manejan flujos de trabajo complejos:
Procesamiento de Pedidos E-commerce (Orquestación): El fulfillment de pedidos de Amazon probablemente usa orquestación internamente. Un servicio orquestador gestiona la secuencia: validar carrito → procesar pago → reservar inventario → crear etiqueta de envío → notificar almacén → enviar email de confirmación. Cada paso debe tener éxito antes de que comience el siguiente, y el orquestador maneja reintentos, timeouts, y compensación si algo falla. Es complejo, pero Amazon necesita procesamiento de pedidos determinístico y rastreable.
Procesamiento de Pedidos E-commerce (Coreografía): Una startup podría usar coreografía en su lugar. El servicio de Pedidos emite “OrderCreated.” El servicio de Pagos escucha, cobra la tarjeta, emite “PaymentSucceeded.” Inventario escucha eso, reserva stock, emite “InventoryReserved.” El servicio de Email escucha múltiples eventos y envía notificaciones apropiadas. Añadir un servicio de puntos de fidelidad es fácil - solo suscríbete a eventos “PaymentSucceeded”. Ningún servicio central conoce el flujo completo.
Coordinación de Viajes Uber (Híbrido): Uber usa ambos. Encontrar un conductor podría ser coreografía - eventos fluyen a través del sistema mientras los conductores responden a solicitudes de viaje. Pero el ciclo de vida real del viaje (recogida → trayecto → llegada → pago) probablemente está orquestado porque es una secuencia estricta con muchos casos edge (conductor cancela, pasajero no aparece, ruta cambia) que necesitan manejo centralizado.
Reclamaciones de Seguros de Salud: El procesamiento de reclamaciones de seguros típicamente está orquestado. Una reclamación debe pasar por validación → verificación de cobertura → autorización previa → verificación de proveedor → cálculo de pago → desembolso en un orden específico con requisitos regulatorios en cada paso. El orquestador asegura cumplimiento y proporciona pistas de auditoría.
Engagement en Redes Sociales: Cuando publicas en Instagram, la coreografía entra en acción. El servicio de posts emite “PostCreated.” El servicio de feed lo añade a los feeds de seguidores. El servicio de notificaciones alerta a usuarios mencionados. El servicio de analytics cuenta impresiones. El servicio de recomendaciones actualiza sus modelos. Todo esto ocurre independientemente, en paralelo, sin ningún coordinador central.
Analogía
La Orquesta vs. Banda de Jazz: Una orquesta tiene un director (orquestador) que explícitamente da entrada a cada sección: violines empiezan, luego se une el metal, luego percusión. Todos siguen la batuta del director. Una banda de jazz no tiene director - cada músico escucha a los otros e improvisa, reaccionando a lo que escucha. Ambos hacen música hermosa, pero el modelo de coordinación es completamente diferente.
La Línea de Montaje vs. la Colmena: Una línea de montaje está orquestada - un capataz programa el trabajo de cada estación, y los coches se mueven en secuencia. Una colmena está coreografiada - ninguna abeja reina le dice a las trabajadoras individuales a dónde ir. Las abejas huelen feromonas (eventos) e independientemente deciden recolectar néctar, construir panal, o defender la colmena basándose en lo que detectan.
La Operación Militar vs. el Mercado: Una operación militar está orquestada - los comandantes dan órdenes específicas, cada unidad reporta, y la siguiente fase comienza solo cuando los objetivos están confirmados. Un mercado está coreografiado - los vendedores montan, los clientes navegan, las transacciones ocurren, todo basado en participantes reaccionando entre sí sin que nadie controle todo.
La Carrera de Relevos vs. el Maratón: En una carrera de relevos, los relevos están orquestados - corredor 1 debe pasar a corredor 2, quien debe pasar a corredor 3, en secuencia. En un maratón, todos corren independientemente - empiezas cuando suena el disparo (evento), corres tu propia carrera, y terminas cuando terminas. Añadir otro corredor a un maratón es trivial; añadir a un relevo cambia toda la estructura del equipo.
Code Example
// ORCHESTRATION - Central controller
class OrderOrchestrator {
async processOrder(order) {
try {
// Orchestrator explicitly calls each step
const payment = await paymentService.charge(order);
const inventory = await inventoryService.reserve(order.items);
const shipping = await shippingService.schedule(order);
return { payment, inventory, shipping };
} catch (error) {
// Orchestrator handles rollback
await this.compensate(order, error);
}
}
}
// CHOREOGRAPHY - Event-driven
class OrderService {
async createOrder(order) {
// Just emit event, don't orchestrate
await eventBus.publish('OrderPlaced', order);
}
}
class PaymentService {
constructor() {
// Each service listens independently
eventBus.subscribe('OrderPlaced', this.handleOrder);
}
async handleOrder(order) {
await this.charge(order);
await eventBus.publish('PaymentCompleted', order);
}
}
class InventoryService {
constructor() {
eventBus.subscribe('PaymentCompleted', this.handlePayment);
}
async handlePayment(order) {
await this.reserve(order.items);
await eventBus.publish('InventoryReserved', order);
}
}