Scala case class 其字段在不同实例中可以是强制的和可选的

Scala case class whose fields can be mandatory and optional at different instances

我在 akka http 中创建了两个 rest 端点,它将字符串作为输入,使用 Json4s 对其进行解析,然后对其进行处理。我的案例 class 就像 -

final case class A(id: String, name: String, address: String)

第一个端点仅接收 id,而另一个端点接收所有三个字段,我想对两者使用相同的大小写 class A。所以我对名称和地址字段使用了默认值,例如 -

final case class A(id: Stirng, name: String = "", address: String = "")

这对我很有用。但是现在,如果我不在第二个端点发送地址或名称(或两者)字段,它不会抛出异常,说明找不到名称(或地址)。

所以,我的问题是我可以创建一个端点,其中 id 是强制性的,而其他字段无关紧要,而另一个端点是每个字段都是强制性的,使用相同的大小写 class 吗? 将字符串解析为大小写 class 的代码是 -

parse(jsonStr).extract[A]

希望你明白我的意思。

有什么建议吗?

没有你的案例 class 正式定义了你对输入的期望。它不代表歧义。您可以使用可选的并添加支票。但这恰恰违背了提取器的目的。

您可以通过两种方式实现您的目标。

选项 + 验证

名称和地址是可选的,因此您需要处理它们。

case class A(id: String, name: Option[String], address: Option[String])

val json = """{ "id":"1" }"""

// 1st endpoint
val r = parse(json).extract[A]
r.name.getOrElse("foo")
r.address.getOrElse("bar")

// 2nd endpoint
val r2 = parse(json).extract[A]
r2.name.getOrElse(/* boom! */)

默认 JObject + 合并

或者您可以使用替代的 JObject 为您的输入提供默认值。

case class A(id: String, name: String, address: String)

val json = """{ "id":"1"  }"""

val defaultValues = JObject(("name", JString("foo")), ("address", JString("bar")))

// 1st endpoint
val r = defaultValues.merge(parse(json)).extract[A]

// 2nd endpoint
val r2 = parse(json).extract[A] // boom! again