validation - Validadores de reglas empresariales y controlador de comandos en CQRS
command nservicebus (1)
Es importante saber que los comandos se pueden rechazar después de enviarlos al controlador.
Como mínimo, puede encontrar una infracción de concurrencia que no se puede detectar hasta que se toca la raíz del agregado.
Pero también, la validación que puede ocurrir fuera de la entidad es simple validación. No solo las longitudes de cadena, los rangos numéricos, la coincidencia de expresiones regulares, etc., sino también la validación que se puede satisfacer razonablemente a través de una consulta o vista, como la exclusividad de una colección. Es importante recordar que es probable que la validación que implica una vista materializada sea finalmente consistente , que es otra razón por la cual un comando podría ser rechazado desde el agregado, dentro del controlador de comando. Dicho esto, para adelantarse a la situación, a menudo uso modelos de lectura para conducir las opciones de IU que solo permiten acciones válidas.
La validación que no puede ocurrir fuera de una entidad es su validación de la lógica de negocios. Esta validación depende del contexto en el que se ejecuta ( ver CQRS clarificado de Udi Dahan ).
La lógica empresarial no debe estar en un servicio de validación por separado. Debería estar en tu dominio.
Además, soy de la opinión de que la validación que ocurre en la UI debe volver a verificarse no en el controlador de comandos, sino también en el dominio. Esa validación está ahí para evitar daños en el dominio; si no se realiza fuera del dominio, el dominio aún está sujeto a parámetros no válidos.
El uso de controladores de comando para duplicar esta validación es solo una convención. Si ninguna otra interfaz está enviando comandos, entonces es un duplicado inútil. Si hay varios front end, es solo una opción de dónde colocar la validación duplicada necesaria entonces, y en esos casos prefiero manejarlo en el dominio.
Por último, deberá generar comandos rechazados desde el controlador. Lo logro con excepciones tanto como sea posible.
Soy nuevo en CQRS y estoy tratando de dar sentido a la validación de reglas comerciales en el lado de la escritura (dominio). Sé que la validación del lado del cliente debe hacerse en términos de fecha válida (campo obligatorio, longitud de cadena, correo electrónico válido, etc.) y la validación de la regla comercial / dominio comercial debe hacerse en el dominio. En realidad, las mismas reglas de validación del lado del cliente también deben aplicarse al comando en el dominio, ya que no confiamos en los usuarios.
Entonces, tenemos un comando válido (AddEmailToCustomer) y el controlador de comando se invoca en el comando. Aquí está mi enfoque a la validación.
- Cree instancias de dos validadores de comando en el controlador de comando.
- Primero, valida los datos del comando, al igual que la validación del lado del cliente (campo obligatorio, correo electrónico válido, etc.)
- El segundo validador valida los datos basados en la lógica dentro del segundo validador. Algo así como "¿este cliente está activo?", O lo que sea. Sé que el correo electrónico cambiante no encaja aquí, pero no es importante. Lo importante es que hay una validación comercial aquí.
- Observamos el ValidationResult devuelto por Validator.Validate (ICommand cmd) y descubrimos que hay errores
- No obtendremos un cliente del repositorio para llamar al método UpdateEmail en el AR. Entonces, ¿qué hacemos en este punto?
¿Lanzo y excepción en el controlador de comando y agrego estos errores allí? ¿Envío el comando a la cola de errores o a otro lugar? ¿Respondo con algo como Bus.Reply y devuelvo el código de error? Si es así, ¿qué hago con los mensajes de error? ¿Cómo comunico estos errores al usuario? Sé que puedo enviarlos por correo electrónico más tarde, pero en un escenario web puedo enviar un ID de solicitud en el comando (o usar el ID del mensaje), y sondear para obtener una respuesta con el ID de solicitud y mostrar los mensajes de error al usuario.
Tu guía es apreciada.
Gracias