Uso de análisis de dominios para modelar microservicios

Uno de los mayores desafíos de los microservicios es definir los límites de los servicios individuales. La regla general es que un servicio debe hacer "algo", pero llevarla a la práctica requiere una minuciosa reflexión. No hay ningún proceso mecánico que cree el diseño "correcto". Debe meditar detenidamente sobre el dominio de su empresa, los requisitos y los objetivos. En caso contrario, puede terminar con un diseño incoherente que exhiba algunas características no deseables, como son dependencias ocultas entre servicios, un acoplamiento rígido o interfaces mal diseñadas. En este artículo se muestra un enfoque basado en dominios para el diseño de los microservicios.

En este artículo se usa un servicio de entrega con drones como ejemplo de ejecución. Puede obtener más información sobre el escenario y la implementación de referencia correspondiente aquí.

Introducción

Los microservicios deben diseñarse alrededor de las funcionalidades de la empresa, no en capas horizontales como el acceso a datos o la mensajería. Además, deben tener un acoplamiento flexible y una alta cohesión funcional. Los microservicios exhiben un acoplamiento flexible si puede cambiar un servicio sin necesidad de que los demás se actualicen al mismo tiempo. Un microservicio es coherente si tiene un propósito único y bien definido, como administrar las cuentas de usuario o realizar el seguimiento del historial de entregas. Un servicio debe encapsular el conocimiento del dominio y abstraer ese conocimiento ante los clientes. Por ejemplo, un cliente debe poder programar un dron sin conocer los detalles sobre el algoritmo de programación y el modo en que la flota de drones se administra.

El diseño basado en dominios (DDD) proporciona una plataforma que puede ayudarle en gran medida a diseñar bien los microservicios. El diseño basado en dominios tiene dos fases distintas, tácticas y estratégicas. En el diseño basado en dominios estratégico, se define la estructura a gran escala del sistema. Ayuda a garantizar que la arquitectura permanece centrada en las funcionalidades del negocio. El diseño basado en dominios táctico proporciona un conjunto de modelos de diseño que puede usar para crear el modelo de dominio. Estos modelos incluyen entidades, agregados y servicios de dominio. Los modelos tácticos le ayudarán a diseñar microservicios coherentes y con acoplamiento flexible.

Diagrama de un proceso de diseño basado en dominios (DDD)

En este artículo y en el siguiente, usaremos los siguientes pasos, que aplicaremos a la aplicación Drone Delivery:

  1. Empiece por analizar el dominio de la empresa para conocer los requisitos funcionales de la aplicación. El resultado de este paso es una descripción informal del dominio, que puede perfilarse en un conjunto más formal de modelos de dominio.

  2. A continuación, defina los contextos delimitados del dominio. Cada contexto delimitado contiene un modelo de dominio que representa un subdominio concreto de la aplicación mayor.

  3. Dentro de un contexto delimitado, se aplican los modelos tácticos de diseño basado en dominios para definir las entidades, los agregados y los servicios de dominio.

  4. Use los resultados del paso anterior para identificar los microservicios de la aplicación.

En este artículo, trataremos los tres primeros pasos, relacionados principalmente con el diseño basado en dominios. En el próximo artículo, se identificarán los microservicios. Sin embargo, es importante recordar que el diseño basado en dominios es un proceso iterativo y en curso. Los límites del servicio no son fijos. A medida que una aplicación evolucione, puede decidir dividir un servicio en varios menores.

Nota

Este artículo no muestra un análisis de dominio completo y minucioso. Hemos hecho deliberadamente que el ejemplo sea breve para ilustrar los puntos principales. Para obtener más información sobre el diseño basado en dominios, se recomienda el libro de Eric Evans Domain-Driven Design (Diseño basado en dominios), en el que se usó el término por primera vez. Otra buena referencia es Implementing Domain-Driven Design (Implementación del diseño basado en dominios), de Vaughn Vernon.

Escenario: Drone Delivery

Fabrikam, Inc. está iniciando un servicio de entrega con drones. La empresa administra una flota de drones. Las empresas se registran en el servicio y los usuarios pueden solicitar que un dron recoja los bienes para la entrega. Cuando un cliente programa una recogida, un sistema back-end asigna un dron y notifica al usuario con un tiempo de entrega estimado. Con la entrega en curso, el cliente puede realizar el seguimiento del dron, con una fecha estimada que se actualiza constantemente.

Este escenario implica un dominio bastante complicado. Algunas de las cuestiones empresariales incluyen la programación de los drones, el seguimiento de los paquetes, la administración de las cuentas de usuario, y el almacenamiento y análisis de los datos históricos. Además, Fabrikam desea salir al mercado y evolucionar rápidamente con la incorporación de funciones y funcionalidades nuevas. La aplicación necesita operar en la nube, con un objetivo de nivel de servicio alto. Fabrikam también prevé que distintas partes del sistema tendrán requisitos muy diferentes respecto al almacenamiento y la consulta de datos. Todas estas consideraciones hacen que Fabrikam se decante por una arquitectura de microservicios para la aplicación Delivery de Drone.

Análisis del dominio

El empleo de un método de diseño basado en dominios le ayudará a diseñar los microservicios de modo que cada servicio constituya una solución natural para un requisito empresarial funcional. Puede servirle de ayuda para evitar la trampa que supone permitir que los límites de la organización o las elecciones de tecnología dicten el diseño.

Antes de escribir ningún código, necesita una visión general del sistema que se va a crear. Con el diseño basado en dominios, se empieza por modelar el dominio empresarial y se crea un modelo de dominio. El modelo de dominio es un modelo abstracto del ámbito empresarial. Extrae y organiza el conocimiento del dominio, y proporciona un lenguaje común para los desarrolladores y los expertos en los dominios.

Empiece por asignar todas las funciones empresariales y sus conexiones. Probablemente, esto requerirá la colaboración de los expertos en dominios, los arquitectos de software y otros actores implicados. No es necesario usar ningún formalismo concreto. Esboce un diagrama o dibuje en una pizarra.

A medida que rellene el diagrama, puede empezar a identificar subdominios discretos. ¿Qué funciones están estrechamente relacionadas? ¿Cuáles son fundamentales para la empresa y cuáles proporcionan servicios auxiliares? ¿Cuál es el gráfico de dependencias? Durante esta fase inicial, no se preocupe de las tecnologías ni de los detalles de implementación. Es decir, debe tener en cuenta el lugar donde la aplicación tendrá que integrarse con sistemas externos, como CRM o sistemas de facturación o de procesamiento de pagos.

Ejemplo: Aplicación Drone Delivery

Después del análisis inicial del dominio, el equipo de Fabrikam ha propuesto un borrador que representa el dominio para Drone Delivery.

Diagrama del dominio de Drone Delivery

  • El elemento Shipping (envío) se coloca en el centro del diagrama, ya que es importante para el negocio. Todo lo demás dentro del diagrama existe para habilitar esta funcionalidad.
  • El elemento Drone management (administración de drones) también es esencial para la empresa. La funcionalidad que está estrechamente relacionada con la anterior es Drone repair (reparación de drones) y el uso de predictive analysis (análisis predictivos) que permiten predecir el momento en que los drones tienen que someterse a tareas de mantenimiento.
  • ETA analysis (análisis del tiempo estimado de llegada) proporciona estimaciones de tiempo para la recogida y la entrega.
  • La funcionalidad Third-party transportation (transporte de terceros) permitirá que la aplicación programe métodos de transporte alternativo, si un dron no puede entregar un paquete completo.
  • La funcionalidad Drone sharing (uso compartido de drones) es una posible extensión del negocio principal. La empresa puede tener drones de sobra durante ciertas horas y alquilar el excedente que, de otro modo, permanecería inactivo. Esta característica no estará en la versión inicial.
  • La funcionalidad Video surveillance (vigilancia por vídeo) es otra área que la empresa podría expandir en versiones posteriores.
  • User accounts (cuentas de usuario), Invoicing (facturación) y Call center (centro de llamadas) son subdominios que contribuyen al negocio principal.

Tenga en cuenta que, en este punto del proceso, no hemos tomado decisiones sobre la implementación o las tecnologías. Algunos de los subsistemas pueden implicar a sistemas de software externos o servicios de terceros. Aun así, la aplicación requiere interactuar con estos sistemas y servicios, por lo que es importante incluirlos en el modelo de dominio.

Nota

Cuando una aplicación depende de un sistema externo, existe el riesgo de que el esquema de datos o la API del sistema externo se infiltren en la aplicación, poniendo en peligro a la larga el diseño de la arquitectura. Esto ocurre especialmente con sistemas heredados que pueden no seguir procedimientos recomendados modernos y podrían usar esquemas de datos complejos o API obsoletas. En ese caso, es importante contar con un límite bien definido entre dichos sistemas externos y la aplicación. Considere la posibilidad de utilizar el patrón Strangler Fig o el patrón Anti-Corruption Layer para este fin.

Definición de contextos delimitados

El modelo de dominio incluirá representaciones de cosas reales del mundo, como usuarios, drones, paquetes, etc. Pero eso no significa que todas las partes del sistema deban usar las mismas representaciones para las mismas cosas.

Por ejemplo, los subsistemas que controlan la reparación de drones y el análisis predictivo tendrán que representar muchas características físicas de los drones, como su historial de mantenimiento, kilometraje, antigüedad, número de modelo, características de rendimiento, etcétera. Pero, cuando llega el momento de programar una entrega, no importan esos elementos. El subsistema de programación solo necesita saber si un dron está disponible y el tiempo estimado para la recogida y la entrega.

Si se ha intentado crear un modelo único para ambos subsistemas, sería innecesariamente complejo. También resultaría más difícil para el modelo evolucionar con el tiempo, porque los cambios deberán satisfacer a varios equipos que trabajen en subsistemas independientes. Por lo tanto, a menudo es mejor diseñar modelos independientes que representen la misma entidad del mundo real (en este caso, un dron) en dos contextos diferentes. Cada modelo contiene solo las características y los atributos que sean pertinentes en su contexto determinado.

Aquí es donde entra en juego el concepto del diseño basado en dominios referente a los contextos limitados. Un contexto delimitado es simplemente el límite dentro de un dominio donde se aplica un modelo de dominio en particular. Si examinamos el diagrama anterior, podemos agrupar la funcionalidad teniendo en cuenta si varias funciones compartirán un único modelo de dominio.

Diagrama de contextos delimitados

Los contextos delimitados no están necesariamente aislados entre sí. En este diagrama, las líneas continuas que conectan los contextos delimitados representan los lugares donde dos de ellos interactúan. Por ejemplo, el envío depende de las cuentas de usuario (Accouns) para obtener información sobre los clientes y de la administración de drones (Drone management) para programar los de la flota.

En el libro Domain Driven Design de Eric Evans, se describen varios patrones para mantener la integridad de un modelo de dominio cuando interactúa con otro contexto delimitado. Uno de los principios fundamentales de los microservicios es que los servicios se comunican a través de API bien definidas. Este método se corresponde con dos patrones que Evans llama Open Host Service (servicio de host abierto) y Published Language (lenguaje publicado). La idea subyacente en Open Host Service es que un subsistema define un protocolo formal (API) para que otros se comuniquen con él. Published Language amplía esta idea publicando la API de forma que otros equipos puedan usarla para escribir clientes. En el artículo Diseño de API para microservicios, se trata el uso de OpenAPI Specification (Especificación de OpenAPI), conocida anteriormente como Swagger, para definir las descripciones de la interfaz independiente del lenguaje para las API de REST, expresadas en formato JSON o YAML.

En el resto de este viaje, nos centraremos en el contexto delimitado del envío.

Pasos siguientes

Después de completar un análisis de dominio, el siguiente paso es aplicar el diseño basado en dominios táctico para definir los modelos de dominio con más precisión.