Featured image of post Alimentando el "Read model" con un "Console command"

Alimentando el "Read model" con un "Console command"

TODO description

Antes hemos comentado que para acelerar nuestras aplicaciones, podemos tener dos tecnologías de información. Una algo más lenta, que se asegure que los elementos de dominio son coherentes a través de Aggregates y transacciones a la hora de hacer peticiones de tipo Command, y para las peticiones tipo Query, utilizar otras estrategias, como usar consultas a medida sin pasar por el pesado proceso de hidratar un Aggregate para conseguir información, o usar un motor optimizado para búsquedas como Elasticsearch.

Esa separación de responsabilidades se considera hacer CQRS. En este caso, si usamos una tecnología de información optimizada de tipo Search, como Elasticsearch, hablamos de que tenemos un Read model. Cuando alteramos el estado de un Aggregate, el Domain event que se genera y se libera al Event bus debe se lo suficientemente autónomo a nivel de información como para poder actualizar nuestro Read model, en este caso ElasticSearch.

¿Os acordáis de lo que acabamos de ver en el post de Mejorando el “Command use case” con el “Domain event” sobre publicar un Domain event a un Queue?. Pues ahora vamos a hacer que se consuman los eventos de una Queue y actualizaremos nuestro motor de búsqueda de ElasticSearch.

En este caso usaremos la carta Privileged user. Tiene ese nombre porque es un proceso privilegiado que se ejecuta en el servidor. Normalmente son procesos puntuales o en nuestro caso, un proceso que vigila una Queue y consume su contenido de forma contínua, actualizando la información de nuestro Read model.


Construyendo la primera, segunda y tercera fila - Territory, Flow y Ability

  • El primer iniciador de cualquier caso de uso es un User, External system, o Privileged user. En ese caso es un Privileged user.
  • El Privileged user, según sus relacionados, sólo puede usar cartas de tipo Console command, con lo que la colocaremos a continuación.
  • La carta tiene un color diferente a la de Privileged user, con lo que debemos buscar una carta de territorio. En este caso sería la de User interface.
  • El Console command nos va a generar un Command según los relacionados que tiene, con lo que la colocamos justo al lado en la segunda fila.
  • Para que el Console command pueda generar un Command, necesita información. La única información que recibe del Privileged user es el tipo de eventos que va a consumir. Con lo que en este caso, debemos colocar la carta Ability - Event bus.
  • Siguiendo en la segunda fila, la carta Command tiene otro color. En este caso corresponde a la la carta de territorio Application layer, la cual colocaremos en la primera fila justo encima de la carta Command.
  • La siguiente carta, siguiendo los relacionados, es el Command use case. Como no cambia de color, sabemos que seguimos en Application layer.
  • Mirando relacionados, vemos que puede servirse de Application services y Domain services. Usaremos Application services, que es del territorio de Application layer.
  • En este caso estamos alimentando al llamado Read model, que es una representación de los Aggregates, aunque no lo son como tal, con lo que no tendremos elementos de Domain layer en este caso de uso. Sólo usaremos la carta Read model, que colocaremos al lado de Application services.
  • Si nos fijamos en los relacionados a nivel de tercera fila de Application services, vemos que se sirve de Persistence, Search y Notifications. En este caso nos interesa el primero.
  • Debajo de Application services colocaremos la carta Ability - Persistence
  • Una vez llegados al punto de que hemos actualizado el Read model, no tenemos que dar ninguna respuesta, ya que estamos en un proceso interno sin un usuario real.

Colocando la cuarta fila - Implementation

Cada vez que desplegamos una carta Ability en la tercera fila, debemos agregar en la cuarta fila una carta Implementation. Las cartas Implementation nos dirán la tecnología utilizada para implementar dicha Ability de nuestro Bounded context.

  • Hemos empezado con la carta Ability - Event bus, que es la que tiene la información que necesitamos. Usaremos Symfony messenger como bus y Bus - RabbitMQ como Queue, puesto que en el caso de publicar los eventos usamos esa misma tecnología. En definitiva, deberemos montar las mismas cartas que en el caso de publicar los eventos, pero en este caso, en lugar de publicar, consumiremos los mismos.
  • También hemos desplegado la Ability - Persistence. Con lo que debemos buscar la carta Implementation que se que ajuste a dicha Ability. Dentro de las que disponemos de nuestro stack, en este caso, como vamos a actualizar Search-Elasticsearch, usaremos Persistence - Elasticsearch.
  • No pondremos modificadores de estrategia, ya que su tecnología es NoSQL.

En este primer caso básico, nos quedaría algo así:

Console command consuming events for read model

¿Dónde está el Command bus?

ElasticSearch no tiene transacciones más allá de registrar un Aggregate root, con lo que un Command bus, no nos hace falta. Si aun así, por alguna razón, como registrar en un log las acciones de tipo Command, queremos implementar dicho patrón, haciendo los ajustes oportunos nos queda así:

Console command with command bus consuming events for read model

Licensed under CC BY-NC-SA 4.0
Creado con Hugo
Tema Stack diseñado por Jimmy