2015-09-28 11:58:37 +02:00
|
|
|
/*
|
2016-02-23 12:58:39 +01:00
|
|
|
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
|
2015-09-28 11:58:37 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package docs.http.scaladsl
|
|
|
|
|
|
|
|
|
|
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
|
|
|
|
|
import akka.http.scaladsl.server.Directives
|
|
|
|
|
import org.scalatest.{ Matchers, WordSpec }
|
|
|
|
|
|
2016-02-22 11:45:48 +01:00
|
|
|
import scala.concurrent.Future
|
|
|
|
|
|
2015-09-28 11:58:37 +02:00
|
|
|
class SprayJsonExampleSpec extends WordSpec with Matchers {
|
|
|
|
|
|
2016-02-22 11:45:48 +01:00
|
|
|
def compileOnlySpec(body: => Unit) = ()
|
|
|
|
|
|
|
|
|
|
"spray-json example" in compileOnlySpec {
|
2015-09-28 11:58:37 +02:00
|
|
|
//#example
|
|
|
|
|
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 {
|
2016-02-22 11:45:48 +01:00
|
|
|
complete(Item("thing", 42)) // will render as JSON
|
2015-09-28 11:58:37 +02:00
|
|
|
}
|
|
|
|
|
} ~
|
|
|
|
|
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
|
|
|
|
|
//#
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-02-22 11:45:48 +01:00
|
|
|
|
|
|
|
|
"second-spray-json-example" in compileOnlySpec {
|
|
|
|
|
//#second-spray-json-example
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.stream.ActorMaterializer
|
|
|
|
|
import akka.Done
|
|
|
|
|
import akka.http.scaladsl.server.Route
|
|
|
|
|
import akka.http.scaladsl.server.Directives._
|
|
|
|
|
import akka.http.scaladsl.model.StatusCodes
|
|
|
|
|
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
|
|
|
|
|
import spray.json.DefaultJsonProtocol._
|
|
|
|
|
|
|
|
|
|
object WebServer {
|
|
|
|
|
|
|
|
|
|
// domain model
|
|
|
|
|
final case class Item(name: String, id: Long)
|
|
|
|
|
final case class Order(items: List[Item])
|
|
|
|
|
|
|
|
|
|
// formats for unmarshalling and marshalling
|
|
|
|
|
implicit val itemFormat = jsonFormat2(Item)
|
|
|
|
|
implicit val orderFormat = jsonFormat1(Order)
|
|
|
|
|
|
|
|
|
|
// (fake) async database query api
|
|
|
|
|
def fetchItem(itemId: Long): Future[Option[Item]] = ???
|
|
|
|
|
def saveOrder(order: Order): Future[Done] = ???
|
|
|
|
|
|
|
|
|
|
def main(args: Array[String]) {
|
|
|
|
|
|
|
|
|
|
// needed to run the route
|
|
|
|
|
implicit val system = ActorSystem()
|
|
|
|
|
implicit val materializer = ActorMaterializer()
|
|
|
|
|
|
|
|
|
|
val route: Route =
|
|
|
|
|
get {
|
|
|
|
|
pathPrefix("item" / LongNumber) { id =>
|
|
|
|
|
// there might be no item for a given id
|
|
|
|
|
val maybeItem: Future[Option[Item]] = fetchItem(id)
|
|
|
|
|
|
|
|
|
|
onSuccess(maybeItem) {
|
|
|
|
|
case Some(item) => complete(item)
|
|
|
|
|
case None => complete(StatusCodes.NotFound)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} ~
|
|
|
|
|
post {
|
|
|
|
|
path("create-order") {
|
|
|
|
|
entity(as[Order]) { order =>
|
|
|
|
|
val saved: Future[Done] = saveOrder(order)
|
|
|
|
|
onComplete(saved) { done =>
|
|
|
|
|
complete("order created")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#second-spray-json-example
|
|
|
|
|
}
|
2015-09-28 11:58:37 +02:00
|
|
|
}
|