Lazy formatted recursive JSON type can't be found as implicit value

843 Views Asked by At

I'm using Spray to build a REST API. One of my JSON datatypes are recursive:

case class Container(id: String,
                 name: String,
                 read_only: Boolean,
                 containers: List[Container],
                 content: List[Content])

object PeriusJsonProtocol extends DefaultJsonProtocol {
  implicit val contentFormat = jsonFormat8(Content)
  implicit val containerFormat: JsonFormat[Container] = lazyFormat(jsonFormat5(Container))
}

When completing the route in the HttpService I get the following error:

Error:(49, 18) could not find implicit value for parameter um: spray.httpx.unmarshalling.FromRequestUnmarshaller[Container]
        entity(as[Container]) { container =>
                 ^

Error:(49, 18) not enough arguments for method as: (implicit um: spray.httpx.unmarshalling.FromRequestUnmarshaller[Container])spray.httpx.unmarshalling.FromRequestUnmarshaller[Container].
Unspecified value parameter um.
        entity(as[Container]) { container =>
                 ^

The HttpService looks like this:

import akka.actor.Actor
import spray.routing._
import spray.httpx.SprayJsonSupport._

import PeriusJsonProtocol._

class RestServiceActor extends Actor with RestService {
  def actorRefFactory = context
  def receive = runRoute(projectsRoute)
}

// this trait defines our service behavior independently from the service actor
trait RestService extends HttpService {
  private val PROJECTS  = "projects"

  val projectsRoute =
    path(PROJECTS) {
      get {
        complete(MongoUtil.getAll(PROJECTS, META) map ContainerMap.fromBson)
        //complete(Container("test", "name", false, List(), List()))
      } ~ post {
        entity(as[Container]) { 
          //complete(MongoUtil.insertProject(container))
          complete(container)
        }
      }
    }
}

The complete in the GET works, even though that function returns a list of Containers. The commented out line in the get does not work however and it does not work to implicitly convert the Container in post, as can be seen in the error messages. What should I do to make the container work implicitly and still keep its recursive structure?

1

There are 1 best solutions below

1
On BEST ANSWER

The Container class is a root level json so you need to change the respective implicit to:

implicit val containerFormat: RootJsonFormat[Container] = rootFormat(lazyFormat(jsonFormat5(Container)))