Diseño controlado por dominio (DDD) para arquitectura de datos de microservicios

https://unsplash.com/photos/TgWWeaTAXCM

DDD es un patrón ampliamente discutido e implementado para microservicios . Los microservicios interactúan con los modelos de dominio para salvar el estado de los negocios. Los modelos de dominio son modelos de datos que son específicos del dominio (específicos de cada microservicio). Por ejemplo,

  1. El microservicio de autorización puede tener un modelo de dominio con user_id y otros detalles de autenticación del usuario
  2. El microservicio de pedido puede tener un modelo de dominio con customer_id y otros detalles específicos del cliente.
  3. El microservicio de envío puede tener un modelo de dominio con customer_id, dirección, etc.

Los tres son instancias del objeto comercial del cliente, pero se aplican en contextos diferentes. Básicamente, esto duplica los datos en los microservicios, y eso está bien por DDD. Lo que hemos hecho es establecer un contexto acotado para los datos por microservicio. En el contexto del microservicio de autenticación, el límite del Cliente se define como las credenciales de usuario. En otro contexto, el cliente tiene un límite diferente.

Otra característica de DDD es que los datos y el microservicio que los trata deben ser coherentes y autosuficientes. No hay otros datos que debería necesitar del exterior, y no hay otros datos que actualice fuera del BC. Estos modelos de datos de dominio pueden ubicarse en cualquier tipo de base de datos.

Propagación de datos más allá del contexto limitado en DDD

Puede haber casos en los que se necesite la propagación de datos a través de modelos de dominio (evitando la idea de contexto limitado), por ejemplo, para retirar a un cliente o realizar una actualización. Este es un desafío y, por lo general, se resuelve mediante la eventual coherencia.

Modelos de coherencia eventual

Los cambios se pueden propagar a través de contextos delimitados a través de solicitudes AMQP (utilizando herramientas de mensajería como RabbitMQ) que es asincrónica (sin bloqueo) o mediante solicitudes HTTP que llaman a otro microservicio para realizar la actualización (que es síncrona y bloqueante, esperando la respuesta volver). La naturaleza no bloqueante de los protocolos de mensajería lo convierte en un método de propagación de cambios recomendado.

Encadenar solicitudes HTTP entre microservicios es un anti-patrón (no recomendado) porque si lo hace, tiene una aplicación con SOA pero sin granularidad de microservicios. Por ejemplo, cuando el servicio de envío emite una solicitud HTTP para el servicio de pedido, el pedido emite un HTTP para el servicio de autorización ... y así sucesivamente).

Entonces, si usa HTTP en lugar de AMQP para la propagación de cambios entre modelos de dominio, la conexión en cadena es una mala idea. Especialmente si la solicitud HTTP se emite como resultado de otra solicitud HTTP desde el front-end donde el cliente está esperando una respuesta. Es mejor dejar un mensaje asincrónico y hacer que el modelo pub-sub o impulsado por eventos de MQ se ocupe de él, mientras su servicio responde a la solicitud HTTP del cliente.

Repositorio: patrón agregado

Los modelos de dominio no son capas de persistencia ni capas de infraestructura de datos. Mantienen el estado de las aplicaciones, pero no conserva la lógica empresarial general. La lógica empresarial generalmente se conserva en una base de datos relacional normalizada con la que los microservicios generalmente no tienen que interactuar continuamente. Mientras que los modelos de dominio permanecen en la memoria en ORM (Object Relational Mappers), o permanecen en bases de datos SQL o NoSQL.

Un patrón de repositorio usa un servicio (al que llama repositorio) para realizar operaciones CRUD en datos persistentes. Cualquier microservicio que quiera conservar datos usa el repositorio para hacerlo.

La mejor práctica es que el repositorio utilice agregados para operaciones de inserción/actualización/eliminación. El agregado implica la representación de elementos de datos relacionados en un dominio propio y saludable. El ejemplo clásico es el dominio de la orden.

No puede insertar un artículo de pedido como si fuera un objeto de valor porque tiene una fuerte relación con la entidad de pedido y también tiene su propia identidad. Del mismo modo, no puede eliminar un pedido sin pensar en las implicaciones de perder el artículo de pedido secundario. Hacerlo violará la integridad de la Orden agregada.

De manera similar, la dirección tiene una fuerte relación con el cliente (no se muestra en la imagen) pero en el contexto de la orden agregada, la dirección es un objeto de valor. Order_id de la tabla de pedidos sería la raíz agregada de los pedidos.

El diseño ideal es utilizar un repositorio por agregado, asegurándose de que las operaciones de inserción/actualización/eliminación se realicen como transacciones atómicas que no violen la integridad del agregado. Este enfoque conduce a un mecanismo coherente para mantener los datos de referencia frente a microservicios complejos.

Referencia :

Documentación de Microsoft:

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice

Martin Fowler:

https://martinfowler.com/tags/domain%20driven%20design.html

Compartir: