这是Spray JSON中jsonformat的更好方法

时间:2018-12-07 08:30:09

标签: json scala protocols spray-json

我在Scala中有一个案例类

case class Employee(designation: Int, name: String)

现在我想在Spray中为其定义JSON格式。

据我所知,有两种方法。

implicit lazy val employeeProtocol: RootJsonFormat[Employee] = jsonFormat2(Employee.apply)

implicit lazy val employeeProtocol: RootJsonFormat[Employee] = jsonFormat(Employee, "designation", "name")

以上哪个是更好的方法?它们之间在性能方面有区别吗?

1 个答案:

答案 0 :(得分:1)

当然,这里需要权衡。

您是否有用于JSON值的架构(显式或隐式)?如果是这样,那么对象键是否不同于案例类成员名?如果您对这两个问题的回答均为“是”,那么您将无法使用更明确的jsonFormat版本。如果您对第一个问题的回答是“是”,但是第二个问题的回答是“否”,那么您可能仍想使用更明确的版本,因为它的魔力要少一些。

尽管有充分的理由偏爱jsonFormat2(Employee.apply)版本。假设您有其他版本:

import spray.json._, DefaultJsonProtocol._

case class Employee(designation: Int, name: String)

implicit lazy val employeeProtocol: RootJsonFormat[Employee] =
  jsonFormat(Employee, "designation", "name")

...然后下个月有人来重构案例类,但没有注意到实例:

case class Employee(name: String, designation: Int)

implicit lazy val employeeProtocol: RootJsonFormat[Employee] =
  jsonFormat(Employee, "designation", "name")

恭喜:您有一个程序可以很好地编译,但是以可能非常混乱的方式失​​败。

或者,您可能只是不在乎JSON的样子,并且不想在两个地方都维护成员名称。在这两种情况下,面对重构,更简洁的jsonFormat版本都会更强大。

就性能而言,这两个版本实际上是相同的,实际上jsonFormat2仅在使用运行时反射从目标类型中提取成员名称后才调用jsonFormat。尽管此运行时反射确实要付出(微小的)代价,但提取仅会在程序执行中执行一次(假设您使用vallazy val来定义实例) ,并且在实际解码JSON时,两者的性能完全相同。