Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 754
spydon Avatar asked Oct 14 '15 15:10

spydon


1 Answers

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)))
like image 95
Makis Arvanitis Avatar answered Nov 15 '22 03:11

Makis Arvanitis