2017-06-16 105 views
0

我建立一個非常簡單的服務,應該返回一棵樹一樣通過遞歸情況下,類中定義的結構:上運行時編碼的遞歸數據結構爲JSON與瑟茜http4s

case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

但由於某些原因,我一直得到一個以下編譯錯誤:

Error:(24, 70) could not find implicit value for parameter encoder: io.circe.Encoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]]
implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]]

Error:(24, 70) not enough arguments for method jsonEncoderOf: (implicit encoder: io.circe.Encoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]])org.http4s.EntityEncoder[Seq[com.ansarada.ds.docviewer.server.Main.Node]]. Unspecified value parameter encoder. implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]]

的代碼被編譯,一旦我刪除兒童元素定義,把一個節點到平面物體:

case class Node(id: Int, name: String) 

任何人都可以幫助我定義正確的Json編碼器的情況下嵌套的孩子?

全碼:

import org.http4s.circe._ 
import org.http4s.dsl._ 
import org.http4s.server.blaze.BlazeBuilder 
import org.http4s.server.{Server, ServerApp} 
import org.http4s.{EntityEncoder, HttpService} 

import scalaz.concurrent.Task 

object Main extends ServerApp { 
    import io.circe.generic.auto._ 
    import io.circe.syntax._ 

    case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

    def getNodes: Seq[Node] = Seq(
    Node(0, "#One"), 
    Node(1, "#Two"), 
    Node(2, "#Three") 
) 

    implicit val nodeEncoder: EntityEncoder[Node] = jsonEncoderOf[Node] 
    implicit val nodesEncoder: EntityEncoder[Seq[Node]] = jsonEncoderOf[Seq[Node]] 

    override def server(args: List[String]): Task[Server] = { 
    val nodesService = HttpService { 
     case _ @ GET -> Root/"nodes" => 
     Ok(getNodes.asJson) 
    } 

    BlazeBuilder 
     .bindHttp(8080, "localhost") 
     .mountService(nodesService, "/api") 
     .start 
    } 
} 

回答

0

確定。使用circe json annotations得到它的工作 - @JsonCodec。 步驟一步的指導來解決的問題如上所述:

  1. 先決條件 - 進口瑟茜lib目錄下:

    "io.circe" %% "circe-core" % "0.8.0", 
    "io.circe" %% "circe-generic" % "0.8.0", 
    "io.circe" %% "circe-literal" % "0.8.0", 
    "io.circe" %% "circe-parser" % "0.8.0", 
    
  2. 打開自動編譯器插件在您的build.sbt:

    autoCompilerPlugins := true 
    
  3. 添加scalamacros天堂編譯插件:

    lazy val root = Project("root", file(".")) 
        .settings(
         addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.patch) 
    ) 
    
  4. 標註case類與@JsonCodec:

    @JsonCodec case class Node(id: Int, children: Seq[Node] = Seq()) 
    
  5. 角色響應於JSON:

    Ok(getNodes.asJson) 
    

完整代碼段:

import org.http4s.circe._ 
import org.http4s.dsl._ 
import org.http4s.server.blaze.BlazeBuilder 
import org.http4s.server.{Server, ServerApp} 
import org.http4s.{EntityEncoder, HttpService} 

import scalaz.concurrent.Task 
object Main extends ServerApp { 
    import io.circe.generic.auto._ 
    import io.circe.syntax._ 

    @JsonCodec case class Node(id: Int, name: String, children: Seq[Node] = Seq()) 

    def getNodes: Seq[Node] = Seq(
    Node(0, "#One"), 
    Node(1, "#Two"), 
    Node(2, "#Three") 
) 

    override def server(args: List[String]): Task[Server] = { 
    val nodesService = HttpService { 
     case _ @ GET -> Root/"nodes" => 
     Ok(getNodes.asJson) 
    } 

    BlazeBuilder 
     .bindHttp(8080, "localhost") 
     .mountService(nodesService, "/api") 
     .start 
    } 
}