I have a complex JSON that it's persisted in a database. It's complexity is "segregated" in "blocks", as follows:
Entire JSON:
{
"block1" : {
"param1" : "val1",
"param2" : "val2"
},
"block2" : {
"param3" : "val3",
"param4" : "val4"
},
...
}
In the database, every block is stored and treated individually:
Persisted Blocks
"block1" : {
"param1" : "val1",
"param2" : "val2"
}
"block2" : {
"param3" : "val3",
"param4" : "val4"
}
Every block has a business meaning, so, every one it's mapped to a case-class. I'm building a Play API that stores, updates and retrieves this JSON Structure and i want to validate if someone altered it's data for the sake of integrity.
I'm doing the retrieval (parsing and validation) of every block as follows:
val block1 = Json.parse(block1).validate[Block1].get
val block2 = Json.parse(block2).validate[Block2].get
...
The case-classes:
trait Block
sealed case class Block1 (param1: String, param2: String, ...) extends Block
sealed case class Block2 (param3: String, param4: String, ...) extends Block
sealed case class Request (block1: Block1, block2: Block2, ...)
With the current structure, if some field is altered and doesn't match with the defined type for it Play throws this exception:
[NoSuchElementException: JsError.get]
So, i want to build an accumulative error structure with Scalaz and Validation that catch all possible parsing and validation errors. I have seen this and this so i've coded the validation this way:
def build(block1: String, block2: String, ...): Validation[NonEmptyList[String], Request] = {
val block1 = Option(Json.parse(block1).validate[Block1].get).toSuccess("Error").toValidationNel
val block2 = Option(Json.parse(block2).validate[Block2].get).toSuccess("Error").toValidationNel
...
val request = (Request.apply _).curried
blockn <*> (... <*> (... <*> (...<*> (block2 <*> (block1 map request)))))
}
Note that i'm using the applicative functor <*>
because Request
has 20 fields (building that is a parentheses-mess with that syntax), |@|
applicative functor only applies for case classes up to 12 parameters.
That code works for the happy path, but, when i modify some field Play throws the Execution Exception later described.
Question: I want to accumulate all possible structure faults that Play can detect while parsing every block. How can i do that?
Note: If in some way Shapeless has something to do with this i'm open to use it (i'm already using it).