在 Circe 中使用没有显式配置依赖的蛇形盒
Using snake case without explicit Configuration dependency in Circe
如 documentation 中所述,可以将蛇形大小写转换为 Scala 中惯用的驼峰大小写。我试过了,效果很好。在这里:
implicit lazy val configuration: Configuration = Configuration.default.withSnakeCaseMemberNames
@ConfiguredJsonCodec final case class ModelClass(someField1: String, someField2: Int, someField3: String)
我想在不添加对外部框架的依赖的情况下保持我的模型干净,因此它只包含特定于业务的案例 类。
是否可以避免添加注释 @ConfiguredJsonCodec
并将 implicit lazy val configuration: Configuration
纳入范围?也许它可以在 Decoder
级别配置?
完全有可能。这是一个权衡:
- 如果您的伴生对象中有隐含项,则不必导入它们
- 如果你不想在你的模型中与库耦合,你必须在 trait/object 中排除所有隐式,然后在每次需要它们时 mixin/import 它们
如果您正在开发具有固定堆栈的应用程序,为每个任务选择库,等等 - 将所有隐式都包含在伴侣中只会更干净,更容易维护。
package com.example
package object domain {
private[domain] implicit lazy val configuration: Configuration = ...
}
package com.example.domain
import io.circe.generic.extra._
@ConfiguredJsonCodec
final case class ModelClass(...)
许多实用程序都为此进行了优化,例如enumeratum-circe 使用 mixin 将用于枚举的编解码器添加到伴随对象中。
如果你不想让他们在那里,因为例如你有你的模型在一个模块中,它应该是无依赖性的,那么你将不得不把这些暗示放在其他地方。而这需要手动编写代码,无法绕过它:
package com.example.domain
final case class ModelClass(...)
package com.example.domain.circe
import io.circe._
import io.circe.generic.extra.semiauto._
// if I want a mixin:
// class SomeClass extends Codecs { ... }
trait Codecs {
protected implicit lazy val configuration: Configuration = ...
implicit val modelClassDecoder: Decoder[ModelClass] = deriveConfiguredDecoder[ModelClass]
implicit val modelClassEncoder: Encoder[ModelClass] = deriveConfiguredEncoder[ModelClass]
}
// if I want an import:
// import com.example.domain.circe.Codecs._
object Circe extends Circe
如果你选择这种方式,你就放弃了,例如enumeraturm-circe 提供编解码器的能力,你将不得不手动编写它们。
您必须根据您的用例选择其中之一,但您不能同时获得两者的好处:要么放弃样板文件减少,要么放弃依赖性减少。
如 documentation 中所述,可以将蛇形大小写转换为 Scala 中惯用的驼峰大小写。我试过了,效果很好。在这里:
implicit lazy val configuration: Configuration = Configuration.default.withSnakeCaseMemberNames
@ConfiguredJsonCodec final case class ModelClass(someField1: String, someField2: Int, someField3: String)
我想在不添加对外部框架的依赖的情况下保持我的模型干净,因此它只包含特定于业务的案例 类。
是否可以避免添加注释 @ConfiguredJsonCodec
并将 implicit lazy val configuration: Configuration
纳入范围?也许它可以在 Decoder
级别配置?
完全有可能。这是一个权衡:
- 如果您的伴生对象中有隐含项,则不必导入它们
- 如果你不想在你的模型中与库耦合,你必须在 trait/object 中排除所有隐式,然后在每次需要它们时 mixin/import 它们
如果您正在开发具有固定堆栈的应用程序,为每个任务选择库,等等 - 将所有隐式都包含在伴侣中只会更干净,更容易维护。
package com.example
package object domain {
private[domain] implicit lazy val configuration: Configuration = ...
}
package com.example.domain
import io.circe.generic.extra._
@ConfiguredJsonCodec
final case class ModelClass(...)
许多实用程序都为此进行了优化,例如enumeratum-circe 使用 mixin 将用于枚举的编解码器添加到伴随对象中。
如果你不想让他们在那里,因为例如你有你的模型在一个模块中,它应该是无依赖性的,那么你将不得不把这些暗示放在其他地方。而这需要手动编写代码,无法绕过它:
package com.example.domain
final case class ModelClass(...)
package com.example.domain.circe
import io.circe._
import io.circe.generic.extra.semiauto._
// if I want a mixin:
// class SomeClass extends Codecs { ... }
trait Codecs {
protected implicit lazy val configuration: Configuration = ...
implicit val modelClassDecoder: Decoder[ModelClass] = deriveConfiguredDecoder[ModelClass]
implicit val modelClassEncoder: Encoder[ModelClass] = deriveConfiguredEncoder[ModelClass]
}
// if I want an import:
// import com.example.domain.circe.Codecs._
object Circe extends Circe
如果你选择这种方式,你就放弃了,例如enumeraturm-circe 提供编解码器的能力,你将不得不手动编写它们。
您必须根据您的用例选择其中之一,但您不能同时获得两者的好处:要么放弃样板文件减少,要么放弃依赖性减少。