Ahora vamos a alterar el estado del dominio con una petición. En este caso, para poder cumplir las necesidades del caso más completo de tipo Query que hemos visto antes, vamos a sudar algo más y se van a abrir varios debates.
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 User.
- Si miramos los relacionados de User, vemos que nos sugiere poner una carta Query REST controller o Command REST controller (en nuestro caso queremos hacer un Command), con lo que colocamos dicha carta en la segunda fila.
- La carta tiene un color diferente a la de User, con lo que debemos buscar una carta de territorio. En este caso sería la de User interface.
- El Command REST controller nos va a generar un Command según los relacionados que tiene. Con lo que lo colocamos justo al lado en la segunda fila.
- La carta Command tiene otro color. En este caso corresponde a 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. Application services es del territorio de Application layer, sin embargo, Domain services pertenece a otra capa, como indica su color. En este caso será la carta de territorio Domain layer.
- Si nos fijamos en los relacionados de Application services, vemos que se sirve de las habilidades Persistence, Search y Notifications (corresponde a la tercera fila). En este caso nos interesa el primero, ya que la carta Persistence representa lectura y escritura.
- Colocaremos la carta Ability - Persistence en la tercera fila que representa el territorio de Infrastructure layer, justo debajo de Application services.
- Domain services tiene como relacionados Aggregate root, Aggregate y Value object. Buscaremos dichas cartas y las pondremos a su lado (en este caso podemos apilarlas). Estas tres cartas, en el orden que hemos mencionado, forman nuestra jerarquía de información a nivel de Domain.
- Pese a que las tres cartas anteriores tienen el mismo color que Domain services, aún podemos sacar una carta de territorio más pequeña, para albergarlas dentro de territorio de Domain model.
- Bien. Llegados a este punto, y mirando el ejemplo del caso de uso de tipo Query, esperamos poner una carta Response, pero en este caso debemos debatir si realmente la necesitamos. El User hace una petición para obtener un resultado a través de Command REST controller. En este caso, lo que busca es una Response. Pero el concepto de Response que defiende esta carta es una respuesta con información de Domain. No siempre necesitaremos devolver información cuando modificamos el estado del Domain aparte de un “OK” de nuestro servidor. Eso es debido a que no siempre esa petición se atiende de forma síncrona. A veces se pone en una Queue para procesarse lo antes posible. Otras veces si que forzaremos que sea síncrona porque necesitaremos devolver algo de información, por ejemplo, un identificador de la entidad, para que la aplicación frontal pueda seguir haciendo su trabajo. Evidentemente, qué estrategia tomar dependerá de nosotros, pero aun el caso en que hagamos un proceso síncrono, si pedimos modificar un estado del dominio y le pasamos lo que queremos cambiar, tampoco tiene sentido devolver nada aparte del “OK”. Es por eso, que la Response está ligada a las necesidades específicas del caso de uso.
Rematando con la cuarta fila - Implementation
Como comentábamos en las reglas del juego, la primera carta en la cuarta fila es Territory - Secondary adapters, para recordarnos que sólo pueden haber cartas de dicho color.
Cada vez que desplegamos una carta Ability en la tercera fila, debemos agregar en la cuarta fila como mínimo una carta Implementation. Las cartas Implementation nos dirán la tecnología utilizada para implementar dicha Ability de nuestro Bounded context.
- En nuestro caso, hemos desplegado 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, escogemos Persistence-Postgresql. Eso nos dirá cuál va a a ser nuestra Implementation específica.
- Podemos agregar otras cartas modificadoras antes de colocar Persistence-Postgresql, como por ejemplo, Persistence strategy - ORM o Persistence strategy - SQL. Estas cartas están ahí para generar debate y son lo bastante significativas para que existan en la baraja, ya que según la estrategia que definamos, va a cambiar por completo nuestro código de implementación. Lo podemos abordar con más detalle en el futuro. Ahora escogeremos Persistence strategy - ORM, y la colocaremos entre Persistence y Persistence-Postgresql, desplazando dicha carta un poco mas abajo.
Resultado final
No descuidarse de la “guinda” de las cartas Flow…
- En cualquier momento, tres cartas de tipo Flow pueden interrumpir el flujo y devolver al Command REST controller un error para mostrar al usuario. Dichas cartas son Domain exception, Application exception e Infrastructure exception. Cada una de ellas pueden pararlo todo en su territorio y hacer que el resultado del error se propague hacia las capas superiores.
- Las cartas se pondrán en un ángulo de 45 grados entre Territory y Flow, en el caso de Application exception y Domain exception, y entre Flow e Ability en el caso de Infrastructure exception.