Validaciones personalizadas basadas en otra validación.
Nos gustaría basar algunas de nuestras validaciones JSON en el resultado de la validación de una validación anterior.
Tenemos la clase de caso anterior y nos gustaría introducir una validación JSON que haga que el campo “name” sea obligatorio si “eType = 1” o que el campo “companyName” sea obligatorio si “eType = 2”, además de algunas validaciones específicas por campo que ya tenemos en su lugar al leer el objeto JSON.
implicit val insideObjectReads: Reads[InsideObject] = (
(JsPath \ "name").readNullable[String]
.filter(JsonValidationError("debe tener 10 dígitos"))(name => name.getOrElse("").length == 10) and
(JsPath \ "companyName").readNullable[String]
.filter(JsonValidationError("no debe ser opcional"))(companyName => companyName.isDefined) and
(JsPath \ "eType").read[Int]
.filter(JsonValidationError("eType solo puede tener los valores 1 o 2"))(eType => eType == 1 || eType == 2)
)(InsideObject.apply _)
Podemos hacer estas validaciones dentro del método “apply”, pero nos gustaría hacerlo mientras se lee el objeto JSON. ¿Alguna sugerencia?
Código de muestra: https://scastie.scala-lang.org/wTuhI1zCSJSWKu9Lltcqbw
davy.ai
Para incorporar los resultados de validación anteriores en la validación JSON, podemos usar una combinación de las funciones
flatMap
yorElse
proporcionadas por la biblioteca Play JSON.Primero, podemos crear dos funciones de validación separadas para
name
ycompanyName
:Estas funciones reciben los valores
name
,companyName
yeType
y devuelven unJsResult[String]
, que puede ser tanto unJsSuccess
con el valor validado como unJsError
con un mensaje de error de validación.A continuación, podemos modificar
insideObjectReads
para incorporar estas funciones de validación utilizando las funcionesflatMap
yorElse
:Aquí, primero usamos
flatMap
para llamar avalidateName
yvalidateCompanyName
enname
ycompanyName
, respectivamente, pasando el resultado de la validación deeType
utilizando la funciónreads(json)
como segundo argumento. Estas funciones devuelven unJsResult[String]
, que luego se pasa a la funciónorElse
para recurrir al valor original si la validación falla. Finalmente, añadimos las validaciones restantes como antes.Con esta modificación, el campo
name
será requerido solo cuandoeType = 1
y de manera similar,companyName
será requerido solo cuandoeType = 2
.