如何摆脱这个锅炉板代码

时间:2016-09-27 12:00:20

标签: scala

我正在使用http4s编写一个Web服务项目,每当我编写一个新的数据对象,它被发送到Web服务或从Web服务发出,我需要编写以下代码

import argonaut.{Argonaut, CodecJson}
import org.http4s.{EntityDecoder, EntityEncoder}
import org.http4s.argonaut._

final case class Name (name: String, age : Int)
object Name {
    implicit val codec : CodecJson[Name] = 
        Argonaut.casecodec2(Name.apply, Name.unapply)("name", "age")
    implicit val decoder : EntityDecoder[Name] = jsonOf[Name]
    implicit val encoder : EntityEncoder[Name] = jsonEncoderOf[Name]
}

根据case类中的字段数,我需要使用相应的casecodeX方法(其中x是字段数),然后传递一个字段列表。

请告诉我最好的方法是什么,这样我就不必编写当前伴随对象中的代码。

我的想法是我应该编写一个宏来解析Name类的代码,然后吐出包含编解码器,编码器,解码器的类。但我不知道如何继续实施这个宏。

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

对于编解码器,您可以使用argonaut-shapeless,特别是JsonCodec。对于编码器/解码器,您可以将jsonOf作为decoder传递给您正在调用的函数,隐式推导应该为您完成其余的工作。可悲的是,你无法绕过jsonOfit has been tried

另请阅读:http://http4s.org/docs/0.15/json.html

答案 1 :(得分:1)

不确定它是否真的更好,但你可以从编码器和解码器的通用含义开始:

implicit def decoder[A](implicit cj: CodecJson[A]): EntityDecoder[A] = jsonOf[A]
implicit val encoder[A](implicit cj: CodecJson[A]) : EntityEncoder[A] = jsonEncoderOf[A]

在这一步中,您将阅读2/3的样板文件。 另一部分比较棘手:你可以选择宏观或反思。 我对宏一无所知,但通过反思,减少对你来说不会那么重要:

def generateCodecJson[A](implicit ClassTag[A]): CodecJson[A] = …

并且您仍然需要提供伴随对象并调用该函数来生成CodecJson。不确定是否值得努力。

答案 2 :(得分:-1)

我不熟悉Scala。但我认为你遇到的这种情况与Java类似。在Java中,当您输入当前名称空间中未知的标记时,IDE将导入所有这些代码。您可以尝试使用更好的IDE,例如Intellij IDEA。