Comprendiendo la arquitectura dirigida por eventos: Una guía práctica
La arquitectura dirigida por eventos es uno de los enfoques más elegantes que podemos utilizar al crear productos digitales. En este artículo, explicaré por qué es tan potente y te mostraré cómo implementarla en tus proyectos.
El Problema con el Código Monolítico
Empecemos con un escenario común en el comercio electrónico: crear un pedido. Aunque pueda parecer simple a primera vista, crear un pedido implica múltiples operaciones:
- Almacenar el pedido en la base de datos
- Enviar un correo electrónico de confirmación al cliente
- Generar una etiqueta de envío
- Crear un pedido de compra para el proveedor
- Y potencialmente muchos otros efectos secundarios
Tradicionalmente, podríamos manejar esto con código procedimental que ejecuta todas estas tareas secuencialmente. Sin embargo, este enfoque tiene varios inconvenientes:
- El código se vuelve grande y complejo
- Es difícil de mantener y evolucionar
- Un fallo en cualquier operación secundaria (como enviar un correo electrónico) podría causar que falle toda la creación del pedido
- Diferentes equipos (como logística y comercio electrónico) necesitan coordinar cambios en el mismo código
- Las pruebas se vuelven más complicadas a medida que crece el código
Entra la Arquitectura Dirigida por Eventos
En lugar de tener una pieza masiva de código manejando todo, la arquitectura dirigida por eventos nos permite dividir esto en piezas más pequeñas y manejables. Así es como funciona:
- Creamos un evento (como "PedidoCreado") cuando se guarda el pedido
- Este evento se distribuye a través de un bus de eventos
- Diferentes componentes (listeners o consumers) manejan independientemente sus responsabilidades específicas
Este enfoque aporta varios beneficios:
- Complejidad Reducida: Cada pieza de código tiene una única responsabilidad
- Mejor Manejo de Errores: Un fallo en el envío de un correo electrónico no afectará a la creación del pedido
- Pruebas más Fáciles: Los componentes pueden probarse independientemente
- Mejor Mantenibilidad: Los equipos pueden trabajar en sus componentes específicos sin tocar otros
- Flexibilidad: Añadir o eliminar efectos secundarios se convierte en algo tan simple como añadir o eliminar oyentes
Implementando un Bus de Eventos
Veamos una implementación simple de un bus de eventos en Python. El bus de eventos necesita dos operaciones principales:
1. Suscribir
Este método permite a los componentes registrar su interés en eventos específicos:
def subscribe(self, event_class, callback):
if event_class not in self.subscribers:
self.subscribers[event_class] = [callback]
else:
self.subscribers[event_class].append(callback)
2. Publicar
Este método distribuye eventos a todos los suscriptores interesados:
def publish(self, event):
if event.__class__ not in self.subscribers:
return
for callback in self.subscribers[event.__class__]:
callback(event)
Usando el Bus de Eventos
Así es como podemos usar este patrón para nuestro ejemplo de creación de pedidos:
- Primero, creamos una clase de evento:
@dataclass
class OrderCreated:
order_id: int
items: list
- Luego, creamos nuestros listeners:
def send_confirmation_email(event):
# Manejar envío de correo
def generate_packing_slip(event):
# Manejar generación de etiqueta de envío
- Finalmente, conectamos todo:
event_bus = EventBus()
event_bus.subscribe(OrderCreated, send_confirmation_email)
event_bus.subscribe(OrderCreated, generate_packing_slip)
# Al crear un pedido:
event_bus.publish(OrderCreated(order_id=123, items=[...]))
Más Allá de los Eventos en Memoria
Aunque nuestro ejemplo muestra un bus de eventos en memoria, este patrón puede extenderse para trabajar entre servicios y sistemas. Puedes usar herramientas como:
- RabbitMQ
- Apache Kafka
- AWS EventBridge
- Azure Service Bus
Estas herramientas te permiten implementar arquitecturas dirigidas por eventos entre diferentes servicios, servidores e incluso diferentes empresas.
Conclusión
La arquitectura dirigida por eventos es un patrón potente que ofrece una tremenda flexibilidad y mantenibilidad. Aunque la implementación puede ser bastante simple, los beneficios que aporta a tu código son significativos:
- Componentes desacoplados
- Principio de responsabilidad única
- Pruebas más fáciles
- Mejor manejo de errores
- Mantenimiento simplificado
La próxima vez que te encuentres escribiendo un código que desencadena múltiples efectos secundarios, considera usar un enfoque dirigido por eventos. La inversión inicial en configurar el bus de eventos se amortizará muchas veces a medida que tu aplicación crezca y evolucione.
Mantente al día
Suscríbete a la newsletter para enterarte de las últimas noticias!