Cuando personas se sumergen en el mundo del Event Sourcing, es común que surjan inquietudes recurrentes, las cuales me plantean con frecuencia, junto con los desafíos que encuentran en su camino. En este contexto, es esencial abstenerse de depender exclusivamente de la obtención de datos CRUD, ya que el enfoque basado en eventos ofrece una perspectiva más dinámica y orientada a la evolución de la información.
Asimismo, exponer los flujos de eventos para facilitar la integración se revela como un componente fundamental. Al hacerlo, se fomenta la interoperabilidad y se simplifica la conexión con otros sistemas, potenciando la flexibilidad y la capacidad de evolución.
Les comparto tres recomendaciones clave para orientarte en la exploración de eventos: evitar la dependencia exclusiva de datos CRUD, aplazar optimizaciones prematuras mediante instantáneas y fomentar la exposición de flujos de eventos para facilitar la integración. Estos principios te guiarán hacia una implementación más efectiva y exitosa del Event Sourcing.
CRUD
Mi principal sugerencia en el aprovisionamiento de eventos, que constituye posiblemente el desafío más recurrente que percibo cuando las personas ingresan a esta práctica, se refiere a lo que comúnmente se conoce como «Adquisición de Datos CRUD». Si tienes la costumbre de desarrollar aplicaciones o sistemas siguiendo el estilo Crear-Leer-Actualizar-Eliminar, esto implica que es probable que termines generando eventos derivados de las operaciones de Crear, Actualizar y Eliminar.
Se experimenta un cambio significativo al transitar de una aplicación que simplemente mantiene el estado actual mediante CRUD a que su punto de referencia sea un flujo de eventos. Con frecuencia, los eventos constituyen evidencias del cambio de estado, así como del evento empresarial que provocó dicho cambio de estado. Si se presenta una interfaz de usuario controlada por CRUD en entidades, se acabará con eventos que se derivan de eso. Por ejemplo, se empezaría a generar eventos como ProductCreated, ProductUpdated y ProductDeleted. Siguiendo esta línea, si hay actualizaciones destinadas a propiedades en entidades, se acabará con eventos como ProductQuantityUpdated o ProducePriceChanged. En ambos casos, los eventos simplemente reflejan cambios de estado, pero no explican por qué se produjo el cambio. ¿Cuál fue la razón detrás de un ProductUpdated? Se actualizó, lo cual es positivo, pero ¿por qué sucedió? ¿Y en el caso del evento ProductQuantityUpdated, por qué cambió? ¿Fue a causa de un ajuste de inventario? ¿Recibimos más cantidad del proveedor del producto? ¿Cuál fue la razón de la actualización?.
La claridad es esencial porque no es necesario deducir o adivinar basándose en los datos del evento y en la razón por la que ocurrió. Obtendrás muchas más respuestas a las preguntas al observar un flujo de eventos que sean explícitos. Por ejemplo, ¿cuándo fue la última vez que ejecutamos un ajuste en el inventario? Cuando realizamos ajustes en el inventario, ¿con qué frecuencia estamos disminuyendo la cantidad disponible? No puedes responder a estas preguntas con un ProductoActualizado o un CambioEnLaCantidadDelProducto.t.
Optimización
Una vez que las personas comprenden el Event Sourcing y su funcionamiento, la pregunta más común es: ¡Realmente parece ineficiente tener que recuperar todos los eventos de una transmisión para construir el estado actual! ¿Qué ocurre si tengo eventos en el orden de 1000? Para comprender cómo funciona la obtención de eventos, consulta mi publicación Ejemplo y explicación de la obtención de eventos en un lenguaje sencillo. Como introducción rápida, dispones de una secuencia de eventos para un agregado único, como un Producto con una SKU de ABC123.
Cada vez que deseemos llevar a cabo un comando que añadirá un nuevo evento a la secuencia, por lo general obtendremos todos los eventos de la secuencia, construiremos el estado actual y luego aplicaremos cualquier invariante para el comando que queremos ejecutar. En la secuencia mencionada, si estuviéramos rastreando la «cantidad» como el estado actual, sería 59. Así que volviendo al comentario común de «eso es realmente ineficiente», es una preocupación bastante justificada. La solución a este problema se llama instantáneas, pero son una optimización que no necesariamente se requiere aplicar desde el principio o con frecuencia. En mi experiencia, los flujos de eventos suelen ser finitos y tienen un ciclo de vida con un inicio y un final. Puede haber una duración prolongada para el tiempo que una secuencia está «activa», pero los eventos que se preservan suelen ser limitados. Si tiene muchos eventos y lleva mucho tiempo reconstruir el estado, la creación de instantáneas puede ser útil. Constituyen una manera de crear una representación puntual del Estado.
Después de que se añaden tantos eventos a una secuencia, persistes otro evento en una secuencia separada que representa el estado actual, también registrando en qué versión de la secuencia se encuentra. De esta manera, cuando desees reconstruir el estado actual, primero obtienes la última instantánea y luego obtienes los eventos de la secuencia desde que se creó esa instantánea.
Ahora la pregunta es, ¿cuándo debes crear instantáneas? Si consideras que la secuencia de eventos va a contener muchos eventos, ¿cuántos para una situación dada son muchos? Cada tipo diferente de secuencia de eventos va a tener diferentes eventos que contienen datos distintos. No hay un número mágico de eventos que sea un umbral para crear una instantánea, será específico del caso de uso. Consejo de abastecimiento de eventos, no te apresures a usar instantáneas de inmediato, observa cómo has definido tus secuencias y límites.
Estado y comunicación
Este último desafío en el que las personas se involucran con el Abastecimiento de Eventos es la confusión entre eventos que representan el estado, así como el uso de eventos como una forma de comunicarse con otros límites de servicio. Tu almacén de eventos, las secuencias de eventos y los eventos dentro de una secuencia representan el estado.
En muchas ocasiones, utilizando el suministro de eventos, desarrollará proyecciones como un medio de reflejar el estado actual de las consultas, la interfaz de usuario o los informes. De esta manera, puede consultar una base de datos independiente que haya calculado previamente el estado actual. Esto implica que no es obligatorio extraer todos los eventos de una secuencia para construir el estado actual. Ya está previamente calculado a medida que se generan los eventos (generalmente de forma asincrónica).
Esto indica que tendrás dos bases de datos distintas. Una para tus secuencias de eventos y otra para las representaciones. Todo esto está dentro del mismo límite lógico del servicio. Ahora bien, si empleas un depósito de eventos con soporte para suscripciones, eso no implica que otros límites lógicos de servicio deban acceder directamente al depósito de eventos.
Frecuentemente, las personas adoptan esta práctica como una forma de Pub/Sub que se emplea para la comunicación. Sin embargo, hay una diferencia entre los eventos que se utilizan dentro de un límite lógico para representar el estado y los eventos que se utilizan para comunicarse con otros servicios. No permitirías que un servicio se conectara a la base de datos relacional de otro servicio, ¿cierto? Entonces, ¿por qué acceder a su tienda de eventos?
Los Eventos de Dominio utilizados dentro de un límite de servicio para representar el estado no se consideran eventos de integración. Eventos de Dominio: Eventos Internos Eventos de Integración: Eventos Externos
Conclusiones
Confío en que estos tres consejos sobre la búsqueda de eventos hayan proporcionado valiosas ideas, ya sea para aquellos que están dando sus primeros pasos en este ámbito o para aquellos que han reflexionado sobre el funcionamiento de diversos aspectos relacionados. La exploración de eventos, al adoptar una perspectiva dinámica, la prudencia en optimizaciones y la facilitación de la integración mediante la exposición de flujos, se presenta como una senda prometedora para aquellos que buscan comprender y aplicar de manera efectiva esta metodología. Estos principios, alineados con la experiencia y el aprendizaje continuo, pueden servir como cimientos sólidos en el viaje hacia la comprensión y aprovechamiento pleno de la búsqueda de eventos.