validation - validar - ¿La validación en CQRS tiene que ocurrir por separado una vez en la interfaz de usuario, y una vez en el dominio comercial?
validar formulario jquery antes de enviar (2)
Recientemente leí el artículo CQRS à la Greg Young y aún estoy tratando de entender CQRS.
No estoy seguro de dónde debe ocurrir la validación de entrada, y si posiblemente tiene que suceder en dos ubicaciones separadas (violando así la regla No repetir y, posiblemente, también la separación de preocupaciones).
Dada la siguiente arquitectura de aplicación:
# +--------------------+ ||
# | event store | ||
# +--------------------+ ||
# ^ | ||
# | events | ||
# | v
# +--------------------+ events +--------------------+
# | domain/ | ---------------------> | (denormalized) |
# | business objects | | query repository |
# +--------------------+ || +--------------------+
# ^ ^ ^ ^ ^ || |
# | | | | | || |
# +--------------------+ || |
# | command bus | || |
# +--------------------+ || |
# ^ |
# | +------------------+ |
# +------------ | user interface | <-----------+
# commands +------------------+ UI form data
El dominio está oculto de la interfaz de usuario detrás de un bus de comando. Es decir, la IU solo puede enviar comandos al dominio, pero nunca llega a los objetos de dominio directamente.
La validación no debe ocurrir cuando una raíz agregada está reaccionando a un evento, pero antes.
Los comandos se convierten en eventos en el dominio (por las raíces agregadas). Este es un lugar donde la validación podría ocurrir: si un comando no se puede ejecutar, no se convierte en un evento correspondiente; en su lugar, (por ejemplo) se lanza una excepción que sube a través del bus de comando, de vuelta a la interfaz de usuario, donde queda atrapada.
Problema:
Si un comando no se puede ejecutar, me gustaría desactivar el botón correspondiente o elemento de menú en la interfaz de usuario. ¿Pero cómo sé si un comando puede ejecutarse antes de enviarlo en camino? El lado de la consulta no me ayudará aquí, ya que no contiene ninguna lógica comercial de ningún tipo; y todo lo que puedo hacer desde el lado del comando es enviar comandos.
Soluciones posibles:
Para cualquier comando DoX , introduzca un comando ficticio correspondiente CanDoX que en realidad no hará nada, pero deja que el dominio informe si el comando X podría ejecutarse sin error.
Duplique alguna lógica de validación (que realmente pertenezca al dominio) en la interfaz de usuario.
Obviamente, la segunda solución no es favorable (debido a la falta de separación de las preocupaciones ). Pero, ¿el primero es realmente mejor?
Creo que mi pregunta acaba de ser resuelta por otro artículo, Clarified CQRS por Udi Dahan. La sección "Comandos y Validación" comienza de la siguiente manera:
Comandos y Validación
Al pensar qué podría hacer que un comando falle, un tema que surge es la validación. La validación es diferente de las reglas de negocios ya que establece un hecho independiente del contexto sobre un comando. O bien un comando es válido, o no lo es. Las reglas comerciales, por otro lado, dependen del contexto.
[...] Aunque un comando puede ser válido, aún puede haber razones para rechazarlo.
Como tal, la validación se puede realizar en el cliente, verificando que todos los campos requeridos para ese comando estén allí, los rangos de números y fechas estén bien, ese tipo de cosas. El servidor todavía validaría todos los comandos que llegan, sin confiar en que los clientes hagan la validación.
Considero que esto significa que, dado que tengo una interfaz de usuario basada en tareas, como se sugiere a menudo para que CQRS funcione bien (comandos como verbos de dominio), solo solía atenuar (desactivar) botones o elementos de menú si un comando no puede aún se envía porque algunos datos requeridos por el comando todavía faltan o son inválidos; es decir. la IU reacciona a la validez del comando en sí, y no al efecto futuro del comando en los objetos del dominio.
Por lo tanto, no se requieren comandos CanDoX , y no es necesario filtrar ninguna lógica de validación de dominio en la UI. Lo que la interfaz de usuario tendrá, sin embargo, es algo de lógica para la validación de comandos.
La validación del lado del cliente se limita básicamente a la validación del formato, porque el lado del cliente no puede conocer el estado del modelo de datos en el servidor. Lo que es válido ahora, puede ser inválido 1/2 segundo a partir de ahora.
Por lo tanto, el lado del cliente debe verificar solo si todos los campos obligatorios están completos y si tienen la forma correcta (un campo de dirección de correo electrónico debe contener una dirección de correo electrónico válida, por ejemplo del formulario (. +) @ (. +). (. +) o similar).
Todas esas validaciones, junto con las validaciones de reglas comerciales, se realizan luego en el modelo de dominio en el servicio de Comando. Por lo tanto, los datos que se validaron en el cliente aún pueden dar como resultado Comandos invalidados en el servidor. En ese caso, algunos comentarios deberían poder regresar a la aplicación del cliente ... pero esa es otra historia.