JSON Support
Akka HTTP's marshalling and unmarshalling infrastructure makes it rather easy to seamlessly support specific wire representations of your data objects, like JSON, XML or even binary encodings.
For JSON Akka HTTP currently provides support for spray-json right out of the box through it's
akka-http-spray-json
module.
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.
This is how you enable automatic support for (un)marshalling from and to JSON with spray-json:
- Add a library dependency onto
"com.typesafe.akka" %% "akka-http-spray-json-experimental" % "@version@"
. import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
or mix in theakka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
trait.- 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.
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
- By default, spray-json marshals your types to pretty printed json by implicit conversion using PrettyPrinter, as defined in
implicit def sprayJsonMarshallerConverter[T](writer: RootJsonWriter[T])(implicit printer: JsonPrinter = PrettyPrinter): ToEntityMarshaller[T]
. Alternately to marshal your types to compact printed json, bring aCompactPrinter
in scope to perform implicit conversion.
import spray.json._
// domain model
final case class CompactPrintedItem(name: String, id: Long)
trait CompactJsonFormatSupport extends DefaultJsonProtocol with SprayJsonSupport {
implicit val printer = CompactPrinter
implicit val compactPrintedItemFormat = jsonFormat2(CompactPrintedItem)
}
// use it wherever json (un)marshalling is needed
class MyJsonService extends Directives with CompactJsonFormatSupport {
// format: OFF
val route =
get {
pathSingleSlash {
complete {
// should complete with spray.json.JsValue = {"name":"akka","id":42}
CompactPrintedItem("akka", 42) // will render as JSON
}
}
}
// format: ON
}
}
}
To learn more about how spray-json works please refer to its documentation.
Contents