我正在使用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类的代码,然后吐出包含编解码器,编码器,解码器的类。但我不知道如何继续实施这个宏。
有更好的方法吗?
答案 0 :(得分:2)
对于编解码器,您可以使用argonaut-shapeless,特别是JsonCodec。对于编码器/解码器,您可以将jsonOf
作为decoder
传递给您正在调用的函数,隐式推导应该为您完成其余的工作。可悲的是,你无法绕过jsonOf
,it has been tried。
答案 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。