JSON Support
Akka HTTP’s marshalling and unmarshalling infrastructure makes it rather easy to seamlessly convert application-domain objects from and to JSON. Integration with spray-json is provided out of the box through the akka-http-spray-json
module. Integration with other JSON libraries are supported by the community. See the list of current community extensions for Akka HTTP.
spray-json Support
The SprayJsonSupport trait provides a FromEntityUnmarshaller[T]
and ToEntityMarshaller[T]
for every type T
that an implicit spray.json.RootJsonReader
and/or spray.json.RootJsonWriter
(respectively) is available for.
To enable automatic support for (un)marshalling from and to JSON with spray-json, add a library dependency onto:
Next, provide a RootJsonFormat[T]
for your type and bring it into scope. Check out the spray-json documentation for more info on how to do this.
Finally, import the FromEntityUnmarshaller[T]
and ToEntityMarshaller[T]
implicits directly from SprayJsonSupport
as shown in the example below or mix the akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
trait into your JSON support module.
Once you have done this (un)marshalling between JSON and your type T
should work nicely and transparently.
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import spray.json._
// 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 {
// format: OFF
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")
}
}
// format: ON
}
Pretty printing
By default, spray-json marshals your types to compact printed JSON by implicit conversion using CompactPrinter
, as defined in:
implicit def sprayJsonMarshallerConverter[T](writer: RootJsonWriter[T])(implicit printer: JsonPrinter = CompactPrinter): ToEntityMarshaller[T] =
sprayJsonMarshaller[T](writer, printer)
Alternatively to marshal your types to pretty printed JSON, bring a PrettyPrinter
in scope to perform implicit conversion.
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json._
// domain model
final case class PrettyPrintedItem(name: String, id: Long)
object PrettyJsonFormatSupport {
import DefaultJsonProtocol._
implicit val printer = PrettyPrinter
implicit val prettyPrintedItemFormat = jsonFormat2(PrettyPrintedItem)
}
// use it wherever json (un)marshalling is needed
class MyJsonService extends Directives {
import PrettyJsonFormatSupport._
// format: OFF
val route =
get {
pathSingleSlash {
complete {
PrettyPrintedItem("akka", 42) // will render as JSON
}
}
}
// format: ON
}
val service = new MyJsonService
// verify the pretty printed JSON
Get("/") ~> service.route ~> check {
responseAs[String] shouldEqual
"""{""" + "\n" +
""" "name": "akka",""" + "\n" +
""" "id": 42""" + "\n" +
"""}"""
}
To learn more about how spray-json works please refer to its documentation.