Enmilocalfunciona

Thoughts, stories and ideas.

Desvelando el poder de los microservicios basados en eventos: Guía completa sobre DDD, CQRS y Event Sourcing

Publicado por Rodrigo dos Santos Mendes el

Arquitectura de SolucionesDDDCQRSEvent SourcingEventosArquitectura Empresarial

Introducción

Bienvenido a la exploración de microservicios impulsados por eventos, donde desentrañamos las sinergias del diseño impulsado por dominios (DDD), Segregación de Responsabilidades de Comando y Consulta (CQRS) y el aprovisionamiento de eventos. Esta completa guía le proporcionará los conocimientos necesarios para crear sólidos sistemas basados en eventos.

En la primera sección, desmitificaremos los conceptos fundamentales de DDD, CQRS y Event Sourcing, ilustrando cómo estas metodologías se pueden armonizar para establecer una base sólida para la construcción de microservicios basados en eventos. A continuación, profundizaremos en el papel fundamental de las arquitecturas basadas en eventos, explicando las ventajas del acoplamiento flexible, la escalabilidad, la flexibilidad y la resistencia.

A medida que avanzamos en la comprensión de los conceptos fundamentales, viajaremos a través de los principios básicos de DDD, explorando los aspectos estratégicos y tácticos del diseño. Descubriremos cómo CQRS desacopla eficientemente comandos y consultas, ofreciendo una visión de las ventajas que aporta a la arquitectura. Por último, Event Sourcing ocupa un lugar central, elucidando el concepto de almacenamiento de estado a través de una secuencia de eventos y su perfecta integración con DDD y CQRS.

1. Visión general de DDD, CQRS y Event Sourcing

1.1 Domain-Driven Design (DDD)

Definición: Domain-driven design (DDD) es un enfoque del desarrollo de software que hace especial hincapié en la comprensión y el modelado del dominio del problema. Proporciona un conjunto de principios y patrones para el diseño de sistemas complejos en los que la atención se centra en el dominio, su lógica y las interacciones entre las diferentes partes del sistema.

Los conceptos clave que examinaremos en detalle son Bounded contexts, aggregates, entities y value objects.

1.2 Command Query Responsibility Segregation (CQRS)

Definición: Command Query Responsibility Segregation (CQRS) es un patrón de diseño que sugiere separar las responsabilidades del sistema de comando (escritura) y consulta (lectura). En lugar de utilizar un único modelo para leer y escribir, CQRS utiliza diferentes modelos para optimizar cada operación.

Los conceptos clave que examinaremos son los comandos, las consultas y la separación de los modelos de escritura y lectura.

Untitled

1.3 Event Sourcing

Definición: El Event Sourcing es una técnica en la que una secuencia de eventos determina el estado del sistema. En lugar de almacenar el estado actual, mantiene un registro de los eventos que han ocurrido, y el estado es entonces reconstruido reproduciendo estos eventos.

Los conceptos clave que examinaremos en detalle son Eventos, Almacén de Eventos y Reconstrucción del Estado.

Untitled

2. Comprender los fundamentos del contexto de microservicios en profundidad:

Descripción general: Los microservicios basados en eventos aprovechan los principios de DDD, CQRS y event-sourcing para crear sistemas escalables y flexibles. Al hacer hincapié en la comunicación a través de eventos, los microservicios pueden ser más libremente acoplados, por lo que es más fácil de desarrollar, implementar y escalar los servicios individuales.

Los conceptos clave que examinaremos en detalle son el acoplamiento débil, el escalado, la flexibilidad y la resistencia.

2.1 Domain-Driven Design (DDD)

Definición:

El Domain-driven design (DDD) es un enfoque estratégico y táctico para el desarrollo de software que se centra en una comprensión profunda y un modelado eficaz del dominio del problema. El objetivo principal es alinear el diseño de software estrechamente con las complejidades del dominio del mundo real. DDD introduce un amplio conjunto de principios y patrones que ofrecen un marco sólido para crear sistemas complejos. El objetivo principal es descifrar los entresijos del dominio, su lógica subyacente y las intrincadas interacciones entre los distintos componentes del sistema.

Estos son los conceptos clave que hay que entender:

Bounded Contexts:

  • Definición: Los contextos delimitados consisten en dividir un sistema grande en partes más pequeñas y manejables, cada una de ellas con modelos y conjuntos de reglas distintos. Los Bounded contexts delimitan áreas específicas dentro de un sistema en las que se aplica un lenguaje, un conjunto de reglas y unos modelos concretos. Es como crear una "frontera lingüística" para evitar ambigüedades.
  • Importancia: Esta separación delimita claramente las responsabilidades y la semántica dentro de contextos específicos, evitando confusiones y garantizando una comunicación coherente.
  • Ejemplo: En un sistema de comercio electrónico, el contexto de “Order Management" puede tener reglas y modelos diferentes que el contexto de “Shipping".

Aggregates:

  • Definición: Los agregados son agrupaciones de entidades estrechamente relacionadas, unidas por límites de coherencia definidos y tratadas como una sola unidad. Tienen límites de consistencia bien definidos, y los cambios dentro del agregado se gestionan como una transacción.
  • Significado: Al agrupar entidades, los agregados facilitan el mantenimiento de la consistencia e integridad de los datos dentro de los límites, simplificando las interacciones y transacciones complejas.
  • Ejemplo:** En una plataforma de redes sociales, un agregado “User" puede incluir el perfil del usuario, las publicaciones y los comentarios, garantizando la coherencia dentro de la esfera de influencia del usuario.

Entities and Value Objects:

  • Definición: Las entidades representan conceptos de dominio con identidad, mientras que los objetos de valor encarnan conceptos sin identidad. Las entidades son objetos con identidades distintas, que a menudo representan cosas que cambian con el tiempo. En cambio, los objetos de valor no tienen identidad y son inmutables.
  • Role: Las entidades encapsulan elementos mutables y distinguibles, a menudo soportando cambios, mientras que los objetos de valor son inmutables, proporcionando características sin necesidad de identidad.
  • Ejemplo: En un sistema bancario, una entidad “Customer" puede tener una identidad que persiste a pesar de los cambios, mientras que un objeto de valor “Currency" es intercambiable y no tiene identidad.

El Domain-Driven Design guía a los desarrolladores en la elaboración de soluciones de software que reflejen con precisión las complejidades del dominio del mundo real. Los principios de Bounded Contexts, Agregados y la distinción entre Entidades y Objetos de Valor sirven como piedras angulares para lograr un sistema bien diseñado y centrado en el dominio. Al aplicar DDD, un equipo de desarrollo involucraría a las partes interesadas para capturar las complejidades del dominio empresarial a través de sesiones de modelado colaborativo.

Estos conceptos clave proporcionan un enfoque estructurado que permite a los desarrolladores crear software que refleje la complejidad y riqueza del dominio del mundo real. A través de contextos limitados, agregados y una cuidadosa consideración de entidades y objetos de valor, DDD permite a los desarrolladores crear sistemas que son funcionalmente robustos y profundamente alineados con los matices del problema.

a. Diseño estratégico en DDD:

En la fase de diseño estratégico del Domain-Driven Design (DDD), estamos mirando el panorama general, la estructura global de nuestro software. Implica tomar decisiones de alto nivel que determinan cómo funcionará todo el sistema. Estos son los componentes clave:

  • Aggregates:
    • Explicación: Considera los agregados como grupos de cosas relacionadas y unidas por reglas claras.
    • Significado: Los agregados ayudan a gestionar tareas complejas proporcionando un límite claro y reglas para los elementos agrupados.
    • Ejemplo: En un sistema de carrito de la compra, un agregado podría ser el carrito y los artículos que contiene.
  • Entities and Value Objects:
    • Entidades: Son objetos con identidades distintas que pueden cambiar con el tiempo.
      • Ejemplo: Una entidad Cliente con un ID de cliente único.
    • Objetos de valor: Son objetos sin una identidad especial que permanece invariable.
      • Ejemplo: Un objeto valor podría representar el precio de un artículo en el carrito de la compra.
Untitled

b. Tactical Design in DDD:

Pasando de la visión general a los detalles de codificación, el diseño táctico se centra en cómo poner en práctica las decisiones tomadas en la fase de diseño estratégico:

  • Entities:
    • Características: Las entidades tienen una identidad única y pueden sufrir cambios.
    • Ejemplo: En un sistema bancario, una entidad “User" puede tener un ID de usuario y puede cambiar detalles como su dirección.
  • Value Objects:
    • Características: Los objetos valor no tienen una identidad especial y no cambian.
    • Ejemplo: Un objeto valor podría representar un color o una fecha de nacimiento - cosas que no tienen un ID único pero que son esenciales.
  • Repositories:
    • Función: Los Repositorios actúan como mecanismos de almacenamiento y recuperación de agregados, facilitando su gestión.
    • Ejemplo: En un sistema bibliotecario, un BookRepository ayuda a gestionar libros, añadiéndolos o recuperándolos según sea necesario.

Estas decisiones tácticas de diseño ayudan a los desarrolladores a dar vida a la visión estratégica. Las entidades y los objetos de valor representan los bloques de construcción, y los repositorios proporcionan una forma práctica de manejarlos y organizarlos. Es como convertir el plano arquitectónico en habitaciones reales con muebles. El objetivo es crear un sistema bien organizado y eficaz que se ajuste a los problemas reales que estamos resolviendo.

Untitled

2.2 Command Query Responsibility Segregation (CQRS)

a. Desacoplamiento de comandos y consultas:

La Segregación de la Responsabilidad de las Consultas por Comandos (CQRS) es un enfoque inteligente para diseñar sistemas que se ocupan tanto de las operaciones de escritura (comandos) como de las de lectura (consultas). He aquí un desglose:

  • Comandos:
    • En términos simples, Los comandos son como órdenes para cambiar algo en el estado del sistema.
    • Ejemplo: Piénsalo como dar una orden para actualizar la información de tu perfil en una aplicación.
  • Consultas:
    • En términos simples, Las consultas son solicitudes para obtener información sin cambiar nada.
    • Ejemplo: Es como pedirle a la app que muestre tu información de perfil actual.
  • Separación de los modelos de escritura y lectura:**
    • En términos simples, En lugar de utilizar un modelo para manejar el cambio y la obtención de información, CQRS sugiere tener modelos separados.
    • Por qué es importante: Es como tener dos equipos especializados centrados en hacer actualizaciones (comandos) y obtener información (consultas).

b. Ventajas de CQRS:

La grandeza de CQRS reside en sus ventajas:

  • Optimización de cada operación:
    • Explicación: Al tener modelos separados, puedes ajustarlos para sus tareas específicas.
    • Ejemplo: Su modelo de actualización (comandos) puede ser super eficiente en el manejo de cambios, mientras que su modelo de lectura (consultas) puede obtener información rápidamente.
  • Escalabilidad mejorada:
    • Explicación: Dado que los comandos y las consultas se manejan por separado, puede escalarlos de forma independiente en función de su carga de trabajo.
    • Ejemplo: Si tu sistema recibe más peticiones de actualización que de lectura, puedes escalar la parte de gestión de comandos sin afectar a la parte de gestión de consultas.
  • Complejidad simplificada:
    • Explicación: Desacoplar los comandos y las consultas reduce la complejidad del sistema en general.
    • Ejemplo: Es como tener diferentes especialistas para diferentes tareas, cada uno centrado en lo que mejor sabe hacer.

CQRS es similar a tener un equipo dedicado a realizar cambios y otro a obtener información. Esta separación permite afinar las habilidades de cada equipo, creando un sistema más eficiente y escalable. Es una forma inteligente de organizar tareas que se alinean con el funcionamiento de su sistema.

Untitled

2.3 Event Sourcing

a. Almacenamiento de estados como una secuencia de eventos:

Event Sourcing es una técnica inteligente que invierte la forma tradicional de almacenar los estados del sistema. He aquí un desglose:

  • Definición:
    • En términos simples, en lugar de guardar el estado actual de un sistema, guardamos un registro de cada cosa significativa que ha sucedido.
    • Ejemplo: Es como llevar un diario de todos los acontecimientos importantes de tu vida en lugar de limitarte a anotar tu estado de ánimo actual.
  • Concepto clave - eventos:
    • Explicación: Los eventos son como registros inmutables de incidentes dignos de mención en el sistema.
    • Ejemplo: En un sistema de comercio electrónico, un evento podría ser "Order Placed" o "Item Shipped".
  • Concepto clave - almacenamiento de eventos:
    • Explicación: El almacenamiento de eventos es donde registramos todos estos eventos.
    • Ejemplo: Piénsalo como una estantería donde cada evento tiene su libro, y lo almacenamos cronológicamente.

b. Ventajas y retos del Event sourcing:.

El aprovisionamiento para eventos presenta tanto ventajas como retos:

  • Ventajas
    • Historial completo del sistema
      • Explicación: Tienes un historial completo de todo en tu sistema.
      • Ejemplo: Puede rastrear hacia atrás para ver cómo cambió el inventario de su tienda de comercio electrónico.
    • Flexibilidad en la Reconstrucción de Estados:
      • Explicación: Puedes recrear el estado actual reproduciendo eventos.
      • Ejemplo: Si quieres conocer el estado actual de tu inventario, reproduce todos los eventos relacionados con cambios en el inventario.
  • Desafíos:
    • Complejidad y Curva de Aprendizaje:
      • Explicación: Event Sourcing puede parecer un poco complicado al principio.
      • Ejemplo: Es como aprender a utilizar una nueva herramienta-toma algún tiempo acostumbrarse a ella.
    • Espacio de Almacenamiento:
      • Explicación: Mantener un historial de eventos puede ocupar más espacio de almacenamiento.
      • Ejemplo: Es como guardar todas las versiones de un documento, lo que requiere más espacio que guardar sólo la versión final.
Untitled

c. Integración con DDD y CQRS:.

El aprovisionamiento de eventos encaja como una pieza de puzzle en el diseño orientado al dominio (DDD) y la segregación de responsabilidad de consulta de comandos (CQRS):

  • Integración con DDD:
    • Explicación: Event Sourcing se alinea perfectamente con el énfasis de DDD en la comprensión y el modelado del dominio del problema.
    • Ejemplo: Es como tener un registro detallado de los eventos clave del dominio de tu sistema.
  • Integración con CQRS:
    • Explicación: Event Sourcing complementa CQRS proporcionando una forma clara de gestionar comandos y sus eventos resultantes.
    • Ejemplo: Es similar a tener una base sólida para manejar eficientemente comandos y consultas.

Event Sourcing es como tener un libro de cuentos detallado del viaje de su sistema. Le ayuda a comprender el pasado y le proporciona una forma flexible de recrear y adaptarse al presente.

Untitled

Conclusión

Recapitulación de DDD, CQRS y Event sourcing

Al revisar los conceptos fundamentales del Diseño Orientado al Dominio (DDD), la Segregación de Responsabilidades de Consulta de Comandos (CQRS) y Event Sourcing hemos sentado las bases para comprender cómo estos principios interactúan para dar forma a microservicios robustos orientados a eventos. El énfasis en la comprensión del dominio, la separación de preocupaciones y la adopción de arquitecturas centradas en eventos proporcionan un enfoque holístico para el desarrollo de software.

Aprovechar la potencia de las arquitecturas basadas en eventos

Para concluir esta exploración, invitamos a adoptar el poder transformador de las arquitecturas centradas en eventos. Al adoptar los principios descritos y aprovechar las capacidades de estos enfoques, los desarrolladores no sólo pueden crear sistemas de software, sino también soluciones de ingeniería que se adaptan a escala y prosperan en el panorama dinámico del desarrollo de software moderno.

Gracias por acompañarnos en este viaje. Que tus incursiones en los microservicios basados en eventos sean tan dinámicas y gratificantes como las arquitecturas que creas.

Este es el primero de una serie de artículos que detallan cómo implementar un microservicio dirigido por eventos, que hemos visto los conceptos que se utilizarán para construir, este es el primer paso.

Referencias

Domain Driven Design (DDD):

  1. Domain-Driven Design Reference by Eric Evans 12.
  2. The Anatomy of Domain-Driven Design by Scott Millett and Samuel Knight 1.
  3. Domain-Driven Design Quickly by Abel Avram and Floyd Marinescu 1.
  4. Free Domain-Driven Design Learning Resources 3.

CQRS - Command and Query Responsibility Segregation:

  1. CQRS pattern - Azure Architecture Center | Microsoft Learn 1.
  2. An introduction to command query responsibility segregation by IBM Developer 2.
  3. Command Query Responsibility Segregation (CQRS) by Confluent 3.
  4. Command and Query Responsibility Segregation (CQRS) Pattern by Garba 4.

Event Sourcing:

  1. Event Sourcing pattern - Azure Architecture Center | Microsoft Learn 1.
  2. Event Sourcing by Martin Fowler 2.
  3. An introduction to event sourcing by IBM Developer 3.

Integrating CQRS - Command and Query Responsibility Segregation, Event Sourcing, and DDD - Domain Driven Design:

  1. Microservices With CQRS and Event Sourcing by Kiran Kumar 1.
  2. DDD, CQRS and Event Sourcing Explained by AxonIQ 2.
  3. Building systems with microservices, CQRS and event sourcing by AxonIQ 3.
  4. Event-driven Architecture with Microservices using event sourcing and CQRS by Volkan Tüfekçi 4.
  5. Domain Events vs. Integration Events in Domain-Driven Design and Microservices Architectures by Cesar de la Torre 5.