01
Qué es y qué problema resuelve
Un validador de entrada organiza reglas de formato y límites antes del caso de uso. FluentValidation permite expresarlas mediante un contrato separado.
La regla de disponibilidad o autorización no queda resuelta por validar una cadena o un intervalo.
02
Ejemplo paso a paso
Punto de partida Requiere FluentValidation y el DTO del curso. El ejemplo es propio; registra IValidator<CrearReservaDto> y traduce sus errores en el endpoint.
Antes de ejecutar
Requiere FluentValidation y un DTO CrearReservaDto con SalaId, Inicio y Fin. Define el validador e invoca ValidateAsync explícitamente. No incluye endpoint ni escritura; la integración debe impedir invocar el caso de uso cuando el resultado es inválido.
public sealed class CrearReservaValidador : AbstractValidator<CrearReservaDto>
{
public CrearReservaValidador()
{
RuleFor(x => x.SalaId).NotEmpty().MaximumLength(80);
RuleFor(x => x.Fin).GreaterThan(x => x.Inicio);
}
}
// En el adaptador: await validador.ValidateAsync(entrada, ct);Cómo funciona
- Lee cada RuleFor y la condición que comprueba sobre el DTO.
- Construye una entrada válida y otra con sala vacía o intervalo incorrecto.
- Invoca ValidateAsync desde la integración y convierte sus errores en una respuesta consistente.
Resultado esperado: Sala vacía y fin no posterior generan errores antes de guardar.
03
Cuándo usarlo y qué debes evitar
Registrar un validador no garantiza que Minimal APIs lo ejecute. Invoca ValidateAsync deliberadamente y transmite cancelación.
La validación automática tradicional no admite todas las reglas asíncronas y su integración tiene alcance específico. Mantén invariantes también en dominio; una tarea interna puede crear objetos sin pasar por el DTO HTTP.
Ampliación opcional · contexto y variantes del tema
Tres niveles de validación
El transporte valida estructura, tipos y tamaños; el dominio conserva invariantes; la aplicación verifica condiciones que requieren identidad o datos. Un texto de 10.000 caracteres puede rechazarse antes de consultar la base. Un horario invertido tampoco debe llegar a persistencia. La disponibilidad de la sala requiere consulta y protección contra carreras: no es solo una regla del DTO.
Para reglas pequeñas usa funciones puras. Un conjunto grande puede organizarse con FluentValidation, verificando versión y modo de integración. En Minimal APIs, un validador externo no se ejecuta automáticamente por registrarlo: invócalo o configura deliberadamente su integración. Si una regla requiere I/O usa validación asíncrona compatible. Las validaciones que consultan pueden quedar obsoletas: confirma las invariantes compartidas en la escritura.
Punto de partida La función permite reportar varios errores en una sola respuesta. No valida autorización ni disponibilidad. Un DTO nulo o un JSON mal formado se atiende en el límite HTTP.
Antes de ejecutar
Función y uso guiado con el DTO del módulo 2
static Dictionary<string, string[]> Validar(CrearReservaDto entrada)
{
var errores = new Dictionary<string, string[]>();
if (string.IsNullOrWhiteSpace(entrada.SalaId) || entrada.SalaId.Length > 80)
errores["salaId"] = ["Sala obligatoria, máximo 80 caracteres."];
if (entrada.Fin <= entrada.Inicio)
errores["fin"] = ["Debe ser posterior al inicio."];
return errores;
}
// En el endpoint, antes del caso de uso:
var errores = Validar(entrada);
if (errores.Count > 0) return Results.ValidationProblem(errores);Resultado esperado: 400 con errores por campo; ninguna escritura en almacenamiento.
04 · Práctica guiada · opcional
Practica lo aprendido
Invoca ValidateAsync con una entrada que tenga SalaId vacío y fin anterior al inicio. Identifica ambos errores y diseña la condición que impediría llamar al caso de uso.
- 01Prepara CrearReservaDto con SalaId, Inicio y Fin y el paquete FluentValidation.
- 02Invoca explícitamente el validador con la entrada inválida y otra válida.
- 03Inspecciona los errores y escribe la condición del adaptador; la integración HTTP es una ampliación.
Ver solución orientativa
La entrada inválida devuelve errores de SalaId y Fin. Solo una rama con resultado válido debe invocar el caso de uso. Definir la clase o registrarla no ejecuta por sí solo la validación.
05
Comprueba lo aprendido
Responde antes de abrir la explicación. Esta comprobación es opcional y no guarda una puntuación.
01¿Una regla que consulta disponibilidad elimina la carrera de escritura?
No. La condición puede cambiar después de validar; protege la confirmación.
02¿Definir la clase del validador basta para impedir que el endpoint guarde una entrada inválida?
No. El flujo debe invocar ValidateAsync, revisar su resultado y detenerse antes de llamar al caso de uso si hay errores. El registro en DI solo permite obtener la instancia.
Cómo demostrar el objetivo
Compara tu práctica con estos resultados. Si solo diseñaste una prueba, registra su resultado como esperado, no como observado.
- ValidateAsync devuelve errores de sala y de horario para la entrada inválida.
- El diseño del adaptador impide llamar al caso de uso cuando la validación falla.
Qué debes recordar
- La entrada se valida antes de ejecutar el caso de uso.
- El dominio conserva sus invariantes aunque se omita el endpoint.
Tu cuaderno · notas personales
Cuaderno local
Tus notas del contenido
Se guardan únicamente en este dispositivo. Puedes exportarlas cuando quieras.
Material de apoyo · descarga, glosario y referencias
Explicaciones, ejemplos y prácticas propios de Academia de Software. Los fragmentos de integración requieren las dependencias indicadas; el ZIP contiene el núcleo de consola. Las lecturas externas se consultan en su sitio original y conservan sus condiciones. Procedencia y condiciones de uso.