sas*_*has 10 validation serialization scala version scala-cats
我有一组配置JSON文件,如下所示:
{
"version" : 1.0,
"startDate": 1548419535,
"endDate": 1558419535,
"sourceData" : [...] // nested json inside the List.
"destData" : [...] // nested json inside the List.
"extra" : ["business_type"]
}
Run Code Online (Sandbox Code Playgroud)
有几个这样的配置文件.它们是固定的,只驻留在我的代码目录中.每个配置文件的内部表示由我的case类给出Config:
case class Attribute(name: String, mappedTo: String)
case class Data(location: String, mappings:List[Attribute])
case class Config(version: Double, startDate: Long, endDate: Long, sourceData: List[Data],
destData: List[Data], extra: List[String])
Run Code Online (Sandbox Code Playgroud)
我有三个班Provider,Parser和Validator.
Provider有一个方法getConfig(date: Long): Config.它必须返回满足的配置startDate <= date <= endDate(理想情况下,应该存在一个这样的配置,startDate以endDate定义要返回的配置版本).getConfig调用一个Parser被调用的方法parseList(jsonConfigs: List[String]): Try[List[Config]].是什么parseList做的是试图反序列化列表中的所有的configs,每到案件类的一个实例Config.即使一个JSON无法反序列化parseList返回,scala.util.Failure否则返回scala.util.Success[List[Config]].scala.util.Success[List[Config]]从上一步中返回,getConfig然后最后调用一个方法里面Validator叫def validate(List[Config], Date): ValidationResult[Config],并返回它的结果.因为我想要累积所有错误,我正在使用Cats验证进行验证.我甚至在这里问了一个关于它的正确用法的问题.validate执行以下操作:检查列表中是否只有一个 Config适用于给定的日期(startDate <= date <= endDate),然后对其执行一些验证Config(否则返回一个invalidNel).我执行一些基本的验证,Config比如检查各种Lists和Strings是否为空等.我还执行一些语义验证,比如检查每个字段中的每个字符串extra是否存在于mappings每个source/dest Data等等.Cats Validated仅仅是收集所有错误(并且在遇到第一个验证错误时不会快速失败).但是当我到达validate方法时,我已经在parseList方法中做了某种验证.也就是说,我已经验证过parseList我的JSON结构与我的case类一致Config.但我parseList不会像我的validate方法那样积累错误.因此,如果我的json结构和我的case类Config之间存在许多不兼容性,我将只知道第一个.但我想立刻了解它们.如果我开始添加require类似于nonEmptycase类内部的子句(它们将在构造case类时调用,即在解析自身时),例如,它会变得更糟
case class Data(location: String, mappings: List[Attribute]) {
require(location.nonEmpty)
require(mappings.nonEmpty)
}
Run Code Online (Sandbox Code Playgroud)因此,我无法在解析和验证功能之间划清界限.
Cats Validated(我在这里了解它,与Cats非常相似invalidNel).我以为我会首先解析JSON到play-json的JSON AST JsValue,在JsValue我和Configplay-jsons validate方法之间执行结构兼容验证(它累积错误).如果它的精细读取Config案例类来自JsValue并执行后面的验证,我使用Cats给出了上面的例子.(startDate, endDate)包含给定日期的那个.所以,如果我按照我上面提到的解决方案,我已经推转换List[JsValue]到List[Config]以验证阶段.现在,如果JsValueList中的每个成功反序列化成一个Config实例,我可以选择适用的实例,对其执行更多验证并返回结果.但如果有人JsValue不能反序列化我该怎么办?我应该回复他们的错误吗?看起来不直观.这里的问题是我需要解析所有配置以查看哪一个适用于给定日期.这使得我更难以标记解析和验证阶段之间的分离.如何在我的场景中解析和验证配置之间划一条线?我是否更改了维护版本的方式(版本从开始日期到结束日期有效)?
PS:我是一名非常新手的程序员.如果我的问题很奇怪,请原谅我.我自己从未想过在学习Scala时我会花很多时间在验证上.
小智 1
Checks if exactly one Config in the List matches
Run Code Online (Sandbox Code Playgroud)
如果所描述的行为是要求,则格式错误的 JSON 文件将导致验证错误。您可以将 Try[List[ ]] 返回类型更改为 List[Try[ ]] 并在必要时将其与 Validated 集成。该文档可能提供了使用 std lib 类的便捷方法。
如果我们可以选择第一个匹配的,那就是早午餐:进行相同的更改,然后在查找配置时找到列表中匹配的第一个。