I tried the example on the json-support page, and it works as expected.
// domain model
final case class Item(name: String, id: Long)
final case class Order(items: List[Item])
// collect your json format instances into a support trait:
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val itemFormat = jsonFormat2(Item)
implicit val orderFormat = jsonFormat1(Order) // contains List[Item]
}
// use it wherever json (un)marshalling is needed
class MyJsonService extends Directives with JsonSupport {
val route =
get {
pathSingleSlash {
complete(Item("thing", 42)) // will render as JSON
}
} ~
post {
entity(as[Order]) { order => // will unmarshal JSON to Order
val itemsCount = order.items.size
val itemNames = order.items.map(_.name).mkString(", ")
complete(s"Ordered $itemsCount items: $itemNames")
}
}
}
object Main extends App {
implicit val system = ActorSystem("main")
implicit val materializer = ActorMaterializer()
Http().bindAndHandle(new MyJsonService().route, "localhost", 8080)
}
And the result is :
~❯ curl http://127.0.0.1:8080/
{"name":"thing","id":42}%
~❯ curl -H "Content-Type: application/json" -X POST -d '{"items":[{"name":"thing2","id":43}]}' http://localhost:8080
Ordered 1 items: thing2%
So it should work unless you missed something like implicitly define system
or materializer
. In routing-dsl overview it described as follow:
The conversion from Route to flow can either be invoked explicitly using Route.handlerFlow or, otherwise, the conversion is also provided implicitly by RouteResult.route2HandlerFlow.
If this is the problem, maybe you should check that doc as well.
For spray-json, I don't know if it will be maintained. But as it's a lightweight JSON implementation and quite stable now, it's not likely to have a big change in the future.
And ofcoures, if you want to use a Jackson marshaler, it's not so difficult to create your own, like this.