Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastering the Spray Routing DSL

C2d2eb5dc036708dac0282dc78f88a03?s=47 Age Mooij
December 08, 2014

Mastering the Spray Routing DSL

Slides from a talk I did at the Scala Exchange 2014 conference. in London.

Earlier versions of the same talk were given at several meetups and at the Scala.IO 2014 conference in Paris.

C2d2eb5dc036708dac0282dc78f88a03?s=128

Age Mooij

December 08, 2014
Tweet

More Decks by Age Mooij

Other Decks in Programming

Transcript

  1. import exchange.scala._ Preso( title = "Beyond URI Matching", sub =

    "Mastering the Spray Routing DSL", by = Dude("Age Mooij", "@agemooij"), at = ScalaExchange, in = London, on = December.8th.2014 )
  2. val theNext45Minutes = List( Part("Quick Spray Routing intro"), Part("Lots of

    DSL examples & tips") ) val code = Link( "https://github.com/agemooij/preso-scala.exchange-2014") val furtherReading = Link( "http://spray.io/documentation/1.2.2/spray-routing/")
  3. val next = Part("Quick Spray Routing intro")

  4. Example(Route) val thingsApiRoutes: Route = { pathPrefix("things") { pathEnd {

    get { complete(OK, List(Thing("Apple"), Thing("Orange"))) } ~ post { entity(as[Thing]) { thing 㱺 complete(Created) } } } ~ path(LongNumber) { id 㱺 get { complete(OK, Thing(s"Thing # $id")) } } } }
  5. type Route = HttpRequest 㱺 HttpResponse MentalModel(Route) Also("The model that

    akka-http uses")
  6. type Route = RequestContext 㱺 Unit RealModel(Route) case class RequestContext(

    request: HttpRequest, responder: ActorRef, unmatchedPath: Uri.Path ) But("Use the mental model!")
  7. val route: Route = complete("W00t!") val route: Route = _.complete("W00t!")

    val route: Route = { ctx: RequestContext 㱺 ctx.complete("W00t!") } TheSimplest(Route)
  8. val routeOperations = List( RouteFiltering("Pass or reject"), RouteChaining("If rejected, try

    this one"), RouteTransformation( "Modify the request or the response") ) Composing(Routes)
  9. val chained: Route = get { complete("Get") } ~ delete

    { complete("Delete") } ~ (post | put) { complete("Post or Put") } FurtherReading( "http://spray.io/documentation/1.2.2/spray-routing/key-concepts/routes/") ChainingAndFiltering(Routes) val chainingOperator = '~'
  10. val directives = BuildingBlocksFor( "Constructing arbitrarily complex routes" ) val

    whatTheyDo = List( Filter("Pass or reject"), Extract( "Make request values available as extractions"), Transform( "Modify the request or the response"), Complete("Produce a response") ) IntroTo(Directives)
  11. LotsAndLotsOf(Directives)

  12. ExamplesOf(DirectivesThat(Filter || Extract || Complete))) pathPrefix("things") { pathEnd { get

    { complete(OK, List(Thing("Apple"), Thing("iPhone"))) } ~ post { entity(as[Thing]) { thing 㱺 complete(Created) } } } ~ path(LongNumber) { id 㱺 get { complete(OK, Thing(s"Thing # $id")) } } }
  13. ExamplesOf(DirectivesThat(Transform(Requests || Responses))) (decompressRequest() & compressResponseIfRequested(())) { pathPrefix("api") { respondWithHeaders(`Cache-Control`(`no-store`))

    complete(OK, "Not a very useful API...") } } } FurtherReading( "http://spray.io/documentation/1.2.2/spray-routing/key-concepts/directives/")
  14. val next = Part("Lots of DSL examples & tips")

  15. val subSection = Examples(ComposingRoutes)

  16. UseThe(CakePattern)

  17. val route: Route = (get | put | post) {

    complete("W00t!") } val getPutOrPost = get | put | post val route: Route = getPutOrPost { complete("W00t!") } TheEasyWayToBuild(CustomDirectives)
  18. val subSection = Examples(TestingRoutes)

  19. Testing(Routes)

  20. Testing(Routes)

  21. val subSection = Examples(Marshalling)

  22. MarshallingWith(SprayJson)

  23. val supportedJsonLibs = List( PlayJsonSupport, Json4sSupport, LiftJsonSupport ) val alsoSupported

    = List( PlayTwirlSupport, InsertYourCustomMarshallerHere ) MarshallingWith(...)
  24. val subSection = Example(RejectionHandling)

  25. TheDefault(RejectionHandler) val theDefaultBehaviour = SupportsAllPredfinedRejections & Produces(`text/plain`) & ComposesVeryEasily )

    val surrounds = YourEntireRoute
  26. ScopingThe(RejectionHandler)

  27. Custom(RejectionHandlers)

  28. Custom(RejectionHandlers)

  29. AnotherExampleOf(Custom(RejectionHandlers))

  30. val subSection = Examples(WorkingWithFutures)

  31. BlockingOperations(ShouldBeWrappedIn(Futures))

  32. Using(Futures(InYour(Routes)))

  33. Using(Futures(InYour(Routes)))

  34. val subSection = Examples(CustomDirectives)

  35. Custom(Directives(InUse))

  36. Custom(Directives(TheCode))

  37. Custom(Directives(TheCode))

  38. val bonusSection = More(CustomDirectives)

  39. More(Custom(Directives(InUse)))

  40. More(Custom(Directives(TheCode)))

  41. More(Custom(Directives(TheCode)))

  42. val code = Link("https://github.com/agemooij/preso-scala.exchange-2014") val furtherReading = Link("http://spray.io/documentation/1.2.2/spray-routing/") val next

    = theEnd(ThankYou)