En Mi Local Funciona

Technical thoughts, stories and ideas

La aventura de las Arquitecturas Event-Driven (Parte 1)

Publicado por Víctor Madrid el

En este primer artículo vamos a comenzar explicando el origen del enfoque EDA (Event Driven Architecture), que no es otra cosa que explicar la definición, el contexto en el que surge , el uso y las características de un... EVENTO.

"Nunca una cosa tan pequeña ha dado tantos problemas a los desarrolladores...(bueno y a otros sectores...jejeje)"

Consejo

Ponte cómod@ y plantéate como si estuvieras a punto ver la precuela o la versión "origin" de una película importante.

Cuando un@ ve este tipo de películas normalmente presta una especial atención porque esto ayudará a entender mucho mejor lo que vendrá después y así no ira perdido.

El tema puede que parezca NO muy novedoso y del que ya se ha hablado mucho, pero las aclaraciones de este artículo tienen varios objetivos:

  • Aprender la parte teórica y de definición de la entidad "evento" (que nunca se tiene claro que tiene que contener..)
  • Despejar dudas en cosas que no se suelen tener claras inicialmente
  • Entender aquellos aspectos que "sin querer" se confunden
  • Corregir el uso de lo que se aplica "mal"
  • Ver de forma más amigable el uso de eventos en aquellas arquitecturas donde se usa de alguna manera (y esto lo digo con ironía total...jejeje)

Estos objetivos junto con el enfoque un poco diferente que se va a dar creo que marcarán la diferencia en esta serie de artículos. No se si después de leértelo te invitarán a participar en la iniciativa "Vengadores", pero de momento y para empezar no pinta nada mal con lo que vas a aprender, ¿eh?...

Este artículo está dividido en 6 partes:

  • 1. Introducción
  • 2. ¿Qué es un Evento?
  • 3. Características Básicas de un Evento
    • 3.1. Origen
    • 3.2. Tipología
    • 3.3. Contenido
    • 3.4. Representación
  • 4. Propuesta Básica de Plantilla de Representación de un Evento
  • 5. Actores Básicos implicados con un Evento
  • 6. Conclusiones

1. Introducción

Para entender mucho mejor el contexto en el que nos vamos a mover, conviene explicar una serie de problemas que aparecen en nuestro trabajo diario y que NO son nuevos para la gran mayoría de desarrolladores. Además, su entendimiento facilita el comprender los casos en los que la orientación a eventos y las arquitecturas ED (Event-Driven) son la mejor opción.

  • Problemas del mundo síncrono
  • Problemas de acomplamiento
  • Problemas de integración

Problemas del mundo síncrono

drawing Photo by Brunno Tozzo on Unsplash

Lo "normal" a la hora de trabajar en nuestro día a día, es hacerlo con un enfoque "Request-Driven" y en particular con la tipología "Request/Response" (Petición/Respuesta). Este enfoque hace referencia al hecho de solicitar algo en un momento dado y esperar una contestación asociada en unos tiempos razonables.

El mundo síncrono tiene una serie de aspectos asociados y habituales a tener en cuenta:

  • Acoplamiento point-to-point
    • Se requiere identificar a los elementos participantes o usuarios de la comunicación
    • Se entiende por "usuarios": dos participantes, varios participantes o bien grupos de participantes (uno o varios)
    • Se requiere que los "usuarios" se encuentren disponibles en el momento que se requiera (coincidencia en el tiempo o bien que sean temporalmente dependientes
  • Definición de unos flujos de ejecución donde se depende de la NO producción de una rotura del servicio en ninguno de sus aspectos considerados (disponibilidad, cambios de interfaz, respuesta no estándar, dependencia con terceros, invocaciones encadenadas, etc.), por cierto unas cuentas cosas más:
    • Definición de unos tiempos de procesamiento dependiendo del tipo de flujo
    • Incremento de las integraciones a realizar
    • Problemas con el manejo de las excepciones
    • Posible aparición de estados inconsistentes de las aplicaciones
    • Etc.
  • Se requiere una señal de reloj
    • Mecanismo que informa sobre el tiempo cuando llega un mensaje
  • Aparición de periodos de aceptabilidad
    • Tiempos de espera de la respuesta que en caso de no cumplirse invalide la petición que lo originó
    • Existen algunos casos donde las operativas incorporan una serie de tiempos de latencia extra (retardos controlados y permitidos debidos a diferentes motivos: comunicaciones, seguridad, etc.)
  • Aparición de políticas de reintento
    • Mecanismos utilizados para volver a intentar la solicitud hasta que se produzca la respuesta deseada o se cumpla una condición de parada en los intentos
    • Diferentes enfoques: número, tiempo, tipo de respuesta, etc.
    • No responder de forma adecuada puede generar sobrecarga en las comunicaciones, lo que provoca el incremento de los tiempos, el descenso de la calidad del servicio (en muchos casos se traduce por lentitud) y, si esto dura mucho tiempo, hasta la posible rotura total del servicio
  • Se requiere una infraestructura con unas características concretas para permitir un canal adecuado de comunicaciones -> Mayor complejidad
    • Suele tener recursos limitados
    • El gasto de recursos HW suele ser superior al implicar ciertos aspectos (I/O, hilos, paralelización, etc.)
    • Sus características concretas pueden afectar de forma directa a los tiempos de respuesta ejecutarse
  • Predominio de las operativas online frente a las operativas offline en el trabajo y la funcionalidad diaria utilizada
    • En algunos casos, los errores de la parte online se solucionan con la parte offline (por ejemplo usando batchs), otros casos la parte offline prepara los datos , etc.
  • Se suele considerar un tipo de comunicación rápida (al producirse en tiempo real)

Ejemplos de comunicación síncrona

  • Llamar por teléfono a un amig@ -> audio conferencia
  • Realizar una "video conferencia" con un cliente
  • Mensajería instantánea con enfoque real-time a la hora de intercambiar información
  • ...

Aparece después la comunicación asíncrona para tratar de resolver algunos de los anteriores aspectos...

drawing Photo by Kira auf der Heide on Unsplash

NO creáis entonces que el mundo asíncrono es la solución a todo, lo único que busca este tipo de comunicación es que se produzca de forma diferida en el tiempo, es decir, que NO hace falta que exista coincidencia temporal de los participantes (no real-time o uso en tiempos diferentes).

  • Busca eliminar, siempre que se pueda, el acoplamiento point-to-point obligatorio en un momento determinado

Debido a este cambio conceptual aparecen unas diferencias y problemas a tener en cuenta:

  • Más sencilla a nivel de implementación
    • No requiere una sincronización entre los intervinientes
    • Bajo acoplamiento
  • Enfoque text-based
    • Lo que se quiere comunicar o transmitir "se deja escrito" de alguna manera
    • En algunos casos se requiere algún tipo de almacenamiento fijo o bien temporal
  • No usa señal de reloj
    • Útil cuando los mensajes se generan a intervalos con irregularidad pudiendo llegar a ser puntuales, intermitentes o en streams
  • Minimiza la cantidad de recursos utilizados
  • Se suele considerar un tipo de comunicación lenta (al producirse en los tiempos en que se puede) -> Menos eficiente
  • Posibilidad de tener riesgo de sobrecarga en las comunicaciones
  • Facilita la aparición de varios mecanismos de comunicación asíncrona: Point-to-point y Publish-Subscribe
    • Aparecen patrones concretos: mensajes en queue, publish-subcribe (difusión, consumidor/es exclusivos, competencia de consumidores, grupos de consumo, consumidores balanceados, priorización, expiración, reentrega, etc.)
  • Facilita: la paralelización, el failover, el balanceo de carga y por tanto los sistemas escalables
  • Un mal diseño de estas comunicaciones puede ser el origen del caos
    • Y esto es habitual porque normalmente no se diseñan para funcionar entre si
  • ...

Ejemplos de comunicación asíncrona

  • Entregar un paquete
  • Enviar un email
  • Escribir un Post en un foro de Debate
  • Mensajería instantánea con enfoque "no disponibilidad en el momento" a la hora de intercambiar información
  • ...

Recapitulando, el mundo asíncrono sirve para cubrir unas nuevas necesidades a nivel de requerimientos (funcionales y no funcionales).

Obviamente, habrá que hacer une estudio previo antes de determinar a qué tipo de comunicación nos estamos refiriendo en cada caso.

Problemas de acoplamiento

Muchas de las operaciones que hacemos cada día implementan una lógica de negocio compleja, a pesar de que a priori nos parecen sencillas y además estamos muy acostumbrados a utilizarlas... lo que pasa es que NO nos paramos a pensar lo que implican.

Observamos muchas veces que si nos fijamos con mente analítica, estas operaciones se pueden descomponer en una serie de operaciones asociadas más pequeñas (clásico divide y vencerás), aunque estas pueden ser casi igual de complejas que la operación a la que nos referimos.

Lo normal y lo que se aconseja en estos casos es definir un flujo lineal entre las operaciones. Esto permitirá establecer un comportamiento fácilmente predecible -> Predictable Behavior

  • "Si somos capaces de pintar lo que esta pasando entonces casi se podría decir que lo entendemos"

A veces, esa operación la solemos hacer con tanta frecuencia que NO nos paramos a pensar que implicaciones tiene y como puede diferir de un sitio a otro. Ahí está el truco de porqué empresas que a priori hacen lo mismo son tan diferentes.

Ejemplo "Crear una Transferencia Bancaria genérica"

Ejemplo "Alta de un usuario en un servicio cualquiera"

Problemas de integración

Muchos de los que nos dedicamos al desarrollo sabemos lo que cuesta hacer integraciones (¿cuántas lagrimas habrá derramadas por ello?...jejeje) y ¿sabéis que es lo peor¿... que cada vez existen más y más difícil -> Se incrementa la complejidad

  • Cada día es mas necesaria la integración de todos los sistemas y/o procesos de negocio dentro de una compañía, después hay que añadir al resto de sistemas o compañías colaboradoras. Por ello, aparecen problemáticas nuevas:

    • Transporte de datos entre sistemas
    • Cambios de interfaz
    • Uso de respuestas NO estándares
    • Requerimiento de conversiones o transformaciones intermedias
    • Compatibilidad entre versiones
    • Formato
    • Sobrecarga de batchs
    • (Y mil problemas más...)

Una consideración a la que, la gran mayoría de las veces, NO se le da la importancia que tiene es la identificación de los mecanismos o patrones de comunicación.

Ejemplos de patrones de comunicación

  • Intercambio de ficheros (Files)
  • Bases de datos compartidas (Database)
  • Servicios Web (Web Services): XML, SOAP y REST
  • Mensajería (Messaging)
  • ...

Nota: Dependiendo de cual de ellos elijas se te planteará un nuevo abanico de implicaciones y/o problemas. Y, aún teniendo esto claro, todavía tendrás que incorporar implicaciones y/o problemas de la forma de trabajo específica que se quiera implementar.

Como extra a todo esto, surge entonces la preparación de un plan de testing de integración concreto (con lo que eso con lleva) -> Probar las interfaces entre unidades / componentes / módulos / sistemas.

Hoy en día, integrarse sin hacer ninguna prueba es una locura. Para que todo funcionara a la primera tendrían que estar todos los planetas de la Vía Láctea alineados y, posiblemente, NO vas a tener esa suerte, así que una buena forma de empezar sería teniendo en cuenta los siguientes consejos:

  • Probar inicialmente estos elementos de forma individual
  • Probar de forma integrar uno por uno hasta que se consigue probar todo
  • Disponer de un juego de datos que cubra la mayor parte de las casuísticas
  • Disponer de un entorno lo más real y lo más parecido a lo que se utilizara al final
  • Ejecutarlas durante el desarrollo y no como fase final del ciclo
  • Buscar alternativas para probar cosas que quizás en ese momento todavía no puedan existir -> Aplicar técnicas de mocking de servicios, juegos de datos trucados, servidores dobles, ...
  • Tratar de ir haciendo pruebas durante el desarrollo y no sólo al final del ciclo
  • ...

Ordenar y tener claras las acciones que se van a llevar a cabo para resolver cada problema de integración suele ser un trabajo con gran importancia.

2. ¿Qué es un Evento?

Ya que hay tantas posibles respuestas vamos a empezar por un primer acercamiento.

Lo que dice la RAE (Real Academia Española) para la definición de evento es:

1. m. acaecimiento. -> "Cosa que sucede"

2. m. Eventualidad, hecho imprevisto, o que puede acaecer.

3. m. Suceso importante y programado, de índole social, académica, artística o deportiva.

O bien me quedo con el significado "místico" o con el que se parece casi una "fiesta" / "reunión social". Para el caso que nos toca y, sintiéndolo mucho, vamos a tener que descartar lo de la "reunión social", aunque nos dé mucha pena :-(, y quedarnos con los significados "místicos".

Si, por tanto, se pidiera un enfoque más descriptivo para nuestro ámbito una buena definición sería ...

Aquella información que describe algo (individual y específico) que ha ocurrido en un momento dado (tiempo pasado) en un dominio aplicación concreto y que por tanto puede afectar a uno o más objetos)

Ejemplos

  • "Pago Recibido"
  • "Usuario Creado"
  • "Solicitud de Baja Confirmada"
  • "Cliente Pagado"
  • "Reserva Confirmada"
  • "Vuelo Cancelado"
  • "Vuelos Cancelados"
  • ...

Ayuda:

1) Responde a pregunta "¿Qué ha ocurrido?"

2) Suele tener asociada una acción

Bueno, otra forma de definir un evento sería: "cualquier acción, hecho, problema o cambio (normalmente de estado) de cierta índole en un sistema o en un proceso".

Ejemplo de la Acción "Registrar un nuevo usuario en el sistema"

Algunos eventos asociados: "Solicitar Registrar Nuevo Usuario", "Usuario Creado", "Usuario No Creado por falta de datos" , "Usuario Duplicado", ...

Esta acción tiene asociada alguna tarea que se encarga de persistir los datos por ejemplo en una base de datos genera eventos antes y después de ejecutar la operación

En este punto hay que tener en cuenta la magnitud del evento considerado, ya que este se puede descomponer / fragmentar en eventos pequeños que dependen del evento grande (otra vez el clásico "Divide y vencerás"...)

Ejemplo del Evento "Cierre Aeropuerto Por Meteorología"

Este evento es muy grande y tiene muchas implicaciones, por lo que se puede descomponer en eventos más pequeños como: "Cancelar vuelos", "Cerrar espacio aéreo", etc.

Cualquiera de sus eventos "más pequeños" se pueden descomponer en otros eventos todavía más pequeños, por ejemplo "Cancelar vuelos" generarían otros eventos como "Compensar pasajeros", "Buscar hoteles", etc.

!Sí!...pues ahora empieza la "película" :-)

3. Características de un Evento

Todo evento con el que trabajaremos tendrá una serie características/atributos que ayudarán a definir o diferenciar un evento respecto al resto.

Estas características pueden ser reales (aparecen declaradas de forma concisa) o bien supuesta" (se presuponen dentro de su contexto), así que cuidado con las suposiciones... "En los mundos del negocio y la informática nunca dar nada por supuesto".

¿Qué aspectos/conceptos puedo considerar como características de un evento?

  • Origen
  • Tipología
  • Contenido
  • Representación

Nota: Faltan algunos conceptos extras que aplicarán para añadir "funcionalidad" al evento: Organizativas, Ordenación, Modo de Ejecución,... y que serán explicados en próximos artículos.

3.1. Origen

Una forma de empezar a diferenciar eventos puede ser a partir de su creación:

  • Request-Driven: origen en la petición de algún componente
  • Time-Driven: origen basado en tiempo al ser disparado por un planificador o similar
  • Event-Driven: origen en otro evento al ser el resultado una acción

3.2. Tipología

En la mayoría de los casos esta característica se va a utilizar seguro, ya que proporciona una definición o distinción según su objetivo dentro de la aplicación y/o los contextos de uso:

  • Notificación/Informativo: información que NO debería generar una respuesta o cambio en el sistemas
  • Alerta: información que debería generar una respuesta o cambio en el sistema -> Enfoque Transacción
  • Objeto: registro de un evento a nivel datos y no de comportamiento
  • Negocio:
    • Puede contener datos que ayudan a definir el contexto de un evento -> Serían sus propiedades de aplicación (Por ejemplo, el id interno del usuario sobre el que aplica)
    • En algunos casos esto puede activar un cambio permanente en el sistema
  • Agrupación (evento complejo): abstracción de alto nivel de más de un evento

Recuerda en este punto que el flujo de control de una aplicación puede estar orientado por eventos

3.3. Contenido

El aspecto considerado más doloroso (por lo problemático que es) a la hora de definir un evento. Algunos consejos para ayudar a no cometer fallos comunes son:

  • Buscar una representación clara a nivel de: identificación, descripción y estructura que conforma un evento (Schema)
    • Se suele implementar como un enfoque de "Entidad" / "Entity" (Clase con atributos)
    • Fácilmente modelable en un diagrama de estados finito
  • Implementar con diferentes enfoques de desarrollo:
    • Particularización: Construir eventos específicos para cada uno de los casos de uso (atributos propios con lo que se trabaja, naming concreto, etc.)
    • Generalización: Construir eventos lo más genéricos posibles para cubrir más de un caso de uso (uso de tipos, payload como campo para todo, naming concreto, etc.)
  • El uso de un atributo identificador (id, eventId, etc.)
    • Permite diferenciarlo o reconocerlo frente al resto de eventos
    • Tipología:
      • Anónimo: No es necesario tener un identificador
      • Autoidentificado: Existe el atributo
    • Aunque es opcional se recomienda su uso
    • Lo normal es que si este campo existe, este sea único
    • Es una buena práctica porque puede proporcionar: idempotencia, correlación y traceabilidad
    • Existen diferentes formas de implementar este atributo: secuencia, timestamp, generador de ids, etc.
  • El uso de un atributo autodescriptivo (name, eventName, description, etc.)
    • Determina y/o explica lo que ha ocurrido
    • El o los objetos sobre los que aplica deberán aparecer de alguna forma declarados en el evento
    • Su valor puede tener varios enfoques
      • Occurred: Cuando el evento ya ha ocurrido -> Se suele expresar en un tiempo verbal pasado
      • Arrived: Cuando el evento se va a producir o se quiere que se produzca -> Se suele expresar en un tiempo verbal infinitivo / imperativo
    • Es obligatorio
  • La relación con objetos de negocio (dependerá de los objetos a los que haga referencia)
    • Un evento puede aplicar sobre uno o más objetos de negocio
    • Tipología
      • Property-based: Uso de uno o varios atributos que referencian a las propiedades no identificativas del objeto/s de negocio en el mismo nivel que los atributos del evento. Se suelen representar con el nombre del atributo al que hace referencia
      • Id-based: Uso de uno o varios atributos que referencian a los identificadores del objeto/s en el mismo nivel que los atributos del evento. Se suele representar por el atributo [objectName]Id
      • Payload-based: Uso de un atributo que referencia al objeto/s pero que va establecido como valor de un atributo "payload" del evento donde se puede guardar casi cualquier cosa. Se suele representar por el atributo payload
    • Es obligatorio porque si se usa este aspecto siempre se aplica sobre "algo"
  • El uso de atributos con relevancia en el tiempo ([timeCriteria] que puede ser creationDate, updateDate, duration, ...)
    • Establecen criterios temporales en base a las necesidades de negocio (Por ejemplo, fecha de creación / actualización / borrado, tiempo de vida, duración, periodos de validez, etc.)
    • Es opcional
  • Incorporar la fecha de creación se suele considerar una buena práctica
  • El uso de un atributo de autoría (author)
    • Hace referencia al usuario que lo creo
    • Puede ser una persona, una aplicación, un área de la compañía, etc.
    • Es opcional
  • El uso de un atributo de versionado (version,...)
    • Hace referencia a la posibilidad de que la estructura de un evento haya podido cambiar y es la forma de controlar a cual hace referencia
    • Es opcional
  • El uso de un atributo de formato de datos (eventDataFormat,...)
    • Hace referencia a la posibilidad de tratar alguno de sus atributos con algún tipo de consideración sobre el formato (Por ejemplo: considerar que el campo payload tiene un formato XML)
    • Se utiliza mucho con el campo "payload" para enviar información adjunta al evento y este atributo sirve para dar información sobre el formato de representación del contenido de dicho campo
    • Es opcional

Aclaración de ayuda basada en mi experiencia

Los atributos anteriormente considerados vendrían a ser los más típicos que componen un evento de forma básica y no tan básica, en caso de cualquier otra necesidad se añadiría uno o varios atributos "nuevos" y "sin problemas".

Además se debe tener en cuenta que si un atributo requiere contener algún valor de calculo, este debería ser realizado durante la creación de evento y estar en su interior (ya incluido) durante el flujo de ejecución del evento.

Hay que recordar que cualquier atributo o característica puede tener valores por defecto en base a las necesidades de negocio (así que conviene informarse antes).

3.4. Representación

Muchas veces no se tienen en consideración la forma con la que se va representar o mostrar un evento de nuestro diseño y esto tiene mucha importancia (por ejemplo: cuanto más tardes en tratar de entender que esta haciendo más tiempo tardaras en tratar de resolver un problema) así que te parece si empezamos a pensar en:

  • Hacer uso de un sistema de representación: posicional, CSV, XML, JSON, Etc.
  • Como encaja la parte de contenido dentro de la representación
  • Tratar de homogeneizar todos nuestros desarrollos para mantener estas características de representación todo el tiempo
  • Crear una nomenclatura específica
  • Formalizar los valores del contenido
  • Evaluar la calidad de los valores enviados -> "valores muy malos dentro de un evento hacen que tengamos un evento muy malo"
  • ...

4. Propuesta Básica de Plantilla de Representación de un Evento

Orientaremos la propuesta de plantilla a que podamos disponer de una estructura de ejemplo basada en todo lo que se ha explicado anteriormente. La propuesta puede tener dos enfoques: Schema (con esquema) o Schema-less (sin esquema)

  • Schema (con esquema): Disponer de una estructura en la que formalizar el evento y que exige el cumplimiento de determinadas restricciones a nivel de: campos válidos, orden concreto, valores específicos (concretos, por defecto, indicadores de valor nulos), etc.
  • Schema-less (sin esquema): No disponer de una estructura en la que formalizar el evento por lo que cada vez que se lea uno se exige comprobar los campos disponibles, tratar de dar sentido al orden, que incluyan valores, etc.

Schema sera nuestra elección :-)

Aclaración de "ayuda" basada en mi experiencia

Mi consejo es utilizar siempre que se pueda una propuesta de Schema. Esto se traduce en tener una misma forma de hacer las cosas manteniendo una organización de elementos, así como una forma de uso. Si NO lo haces prepárate a divertirte mucho cuando el mantenimiento adquiera complejidad

Por lo tanto, si quieres definir una arquitectura este sería tu enfoque. :-)

4.1. Schema Genérico

Podemos definir por tanto una propuesta con los campos que incluiríamos (basados en lo que se explicó en el apartado "Contenido") y su ubicación dentro del evento podría ser como la siguiente y que cambiará su representación según la forma de implementarlo:

  eventId: 1 Entero/String [Opcional]
  eventName: 1 String [Obligatorio]

  [objectName]Id: [1..n] Entero/String/Lista<Entero>/Lista<String> [Opcional]

  payload: 1 Objeto/String [Opcional]
  eventDataFormat: 1 String [Opcional]

  [timeCriteria]: [1..n] Depende del criterio [Opcional]

  author: 1 String [Opcional]
  version: 1 String [Opcional]
  • Ejemplo de Schema Genérico en formato XML
<event>

    <eventId>Valor Opcional</eventId>
    <eventName>Valor Obligatorio</eventName>

    <[objectName]Id>Valor/es Opcionales</[objectName]Id>
        ...
    <[objectName]Id>Valor/es Opcionales</[objectName]Id>

    <payload>Valor Opcional</payload>
    <eventDataFormat>Valor Opcional dependiente de payload</eventDataFormat>

    <timeCriteria>Valor Opcional</timeCriteria>
    ...
    <timeCriteria>Valor Opcional</timeCriteria>

    <author>Valor Opcional</author>
    <version>Valor Opcional</version>

</event>
  • Ejemplo de Schema Genérico en formato JSON
{
  eventId: "Valor Opcional",
  eventName: "Valor Obligatorio",

  [objectName]Id: "Valor Opcional" / {<otros valores>},

  payload: "Valor Opcional",
  eventDataFormat: "Valor Opcional dependiente de payload",

  [timeCriteria]: "Valor Opcional",

  author: "Valor Opcional",
  version: "Valor Opcional"
}

4.2. Ejemplos de uso

O bien esto se queda aquí y ya puedes volcar solo o si lo prefieres puedes ver una serie de ejemplos "reales" para ayudar a entender el uso de la plantilla.

  • Ejemplo 1: "Evento de email enviado básico": Evento básico "anónimo" (sin id) sobre el que se desconocen el resto de atributos (Por ejemplo: no se sabe el identificador, a quién iba dirigido, etc.)
{
  eventName : 'EMAIL_SENT'
}
  • Ejemplo 2: "Evento de email enviado": Evento que se diferencia del resto por un "id" secuencial, informa sobre el autor y se trata de la versión 2 de este tipo de evento (requiere retrocompatibilidad, o bien es un nuevo desarrollo), es decir, que puede necesitar un tratamiento especial dentro del contexto de uso. En ese caso tampoco se esta facilitando el identificador del email con el que estaría relacionado
{
  eventId : 18,
  eventName : 'EMAIL_SENT',
  author : 'ACME-APP',
  version : 2
}
  • Ejemplo 3: "Evento de email enviado con temporalidad": Evento igual que el anterior pero incluye un criterios de temporalidad: fecha de creación de evento "Día + Hora" (se correspondería con la fecha del envio)
{
  eventId : 18,
  eventName : 'EMAIL_SENT',
  creationDate : '01-07-2019 21:30:15',
  author : 'ACME-APP',
  version : 2
}
  • Ejemplo 4: "Evento de email enviado con ObjectId": Evento que se diferencia del resto por un "id" timestamp (en este caso puede hacer las veces de fecha de creación), identificando al email al que hace referencia y al usuario que lo emitió con un enfoque de relación de objetos de negocio "id-based"

Nota: Estos atributos particularizan el evento para aplicarse para uno o varios casos muy concretos, además implicará mayor esfuerzo en el mantenimiento de los consumidores

{
  eventId : 20190701213015,
  eventName : 'EMAIL_SENT',
  emailId : 784,
  userId : 4785 
}
  • Ejemplo 5: "Evento de email enviado con ObjectId en payload": Evento que se diferencia del resto por un "id" UUID (Universally Unique Identifier) implementado con un long de 128 bits, los atributos considerados se agrupan esta vez con un enfoque de relación de objetos de negocio "payload-based".

Nota: Se consigue generalizar el evento, al tener los atributos particulares como valores de un atributo genérico "payload"

{
  eventId : 487bc0a5-f52n-3b8d-123z-165678942300,
  eventName : 'EMAIL_SENT'
  payload : {emailId: 101 , userId: 4785}
}
  • Ejemplo 6: "Evento de enviar un email con parámetros": Evento en el que los parámetros del email son pasados como atributos del evento con un enfoque de relación de objetos de negocio "property-based" (aspecto muy interesante, el contenido ya lo entenderá de forma específica su o sus consumidores)

Nota: Se estaría particularizando este evento de forma única y exclusivamente al envío de emails.

Esto es parecido a los problemas de "id-based"

{
  eventId : 20190701213015,
  eventName : 'SEND_EMAIL',
  to : 'destino@acme.com',
  from : 'origen@acme.com',
  subject : 'Importante',
  content : 'Contenido Test'
}
  • Ejemplo 7: "Evento de enviar un email con payload": Evento en el que los parámetros de email son pasados como atributos del evento con un enfoque de relación de objetos de negocio "payload-based". Además se incluye un atributo que informa sobre el formato del campo payload que, aunque tiene la tipología de cadena, internamente tiene un formato JSON.

Nota: En este caso se consigue generalizar el evento

{
  eventId : 20190701113015,
  eventName : 'SEND_EMAIL',
  eventDataFormat  : 'JSON'
  payload : '{
      to : 'destino@acme.com',
      from : 'origen@acme.com',
      subject : 'Importante',
      content : 'Test content'
  }'
}

5. Actores Básicos implicados con un Evento

Rara vez algo en informática en sencillo, pues esto no iba a ser menos:

A nivel básico de participantes hay que considerar:

  • Evento (Evento): Entidad que se corresponde con la unidad de trabajo
  • Productor / Emisor / Publicador de Eventos (Event Publisher): Entidad que crea y publica el evento
    • Desconoce todo lo relacionado con el consumo del evento: entidad consumidora, implicaciones y/o consecuencias
    • En muchos casos genera los datos del evento o bien transforma la información que tiene en un formato adecuado
  • Canal (Channel): Medio donde se publican, localizan, viven y/o son consumidos los eventos
    • Message broker o Message System
    • Se suele trabajar con el concepto de motor de eventos
    • Pueden tener cierta lógica de aplicación sobre los eventos: almacenamiento, expiración, entrega, backup, etc
    • Existen diferentes enfoques: tipo, selector, etc
  • Consumidor/Receptor de Eventos (Event Consumer): Entidad que consume el evento desde un lugar y que por tanto ejecuta/interpreta la lógica de negocio
    • Se subscribe al canal de eventos y no tienen en consideración al productor
    • Conoce como distinguir entre eventos
    • Suelen tener un enfoque asíncrono

Y aquí empieza la "fiesta" ya que hay que tener en cuenta las siguientes consideraciones:

  • Se puede disponer de uno o varios productores para un mismo tipo de evento
  • Se puede disponer de uno o varios consumidores para un mismo tipo de evento
  • Los consumidores se pueden coordinar con diferentes estrategias (grupos, etc.)
  • ...

Unificando todo, hablaremos de estos elementos como "Caso de uso Core", el resto de elemento / actores que pueden aparecer dependerán de la funcionalidad a implementar.

Dicho esto, preparare mentalmente para el siguiente artículo...jejeje

6. Conclusiones

Antes de este tutorial quizás viéramos los eventos con cierto respeto y como un ente abstracto, espero haber podido cumplir las expectativas planteadas al inicio de este articulo

Razonándolo todo con mente de "arquitecto" podemos ver que al final un evento tiene mucho sentido y este todavía adquiere más valor si desde luego tiene una correcta definición.

No te preocupes. Si te ha quedado dudas es normal. He intentado poner en un "tocho" de texto información de ayuda basada en los casos más habituales que podemos tener en la vida real de nuestros proyectos y "complementados" con mi visión.

Os espero en el siguiente artículo para ampliar un poquito más todo lo que se ha contado aquí.

Saludos :-)

Como siempre, si tenéis dudas o preguntas, podéis dejarlas en los comentarios. Y si te ha gustado, ¡no dudes en seguirnos en Twitter!

Víctor Madrid
Autor

Víctor Madrid

Líder Técnico de la Comunidad de Arquitectura de Soluciones en atSistemas. Aprendiz de mucho y maestro de nada. Técnico, artista y polifacético a partes iguales ;-)