Reputation: 10026
I'm currently going through the akka-http documentation & examples. I'm stuck on probably something very trivial: passing in route-configuration with Directives and JsonSupport. I'm following the docs on introduction and json-support
For the JsonSupport I need to make a class extending akka.http.scaladsl.server.Directives
:
class RouteDef extends Directives with JsonSupport {
with JsonSupport
defined by me:
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
How can I now use this class in:
val bindingFuture = Http().bindAndHandle(new RouteDef().route, "localhost", 8082)
The json marshalling is not working, as the jsonsupport is not wired on the route val (I suspect).
A separate question: What is the status of spray-json? Spray is not supported anymore, will spray-json still be maintained or replace by Jackson for example?
Upvotes: 0
Views: 180
Reputation: 51
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.
Upvotes: 1