Skip to content

Instantly share code, notes, and snippets.

@upeter
Last active August 29, 2015 14:06
Show Gist options
  • Save upeter/27489c28a9e1b3392617 to your computer and use it in GitHub Desktop.
Save upeter/27489c28a9e1b3392617 to your computer and use it in GitHub Desktop.
GetOrCreateCookie with Spray
package com.material
import spray.routing.Route
import spray.routing.HttpServiceActor
import akka.actor.ActorSystem
import spray.http.HttpCookie
import akka.io.IO
import spray.can.Http
import akka.actor.Props
import java.util.UUID
import spray.can.Http.Bind
import spray.routing._
class GetOrCreateCookieSampleActor extends HttpServiceActor {
def receive = runRoute(route)
lazy val route =
path("session-cookie-urs") {
solutionUrs.shopperCookieUrs { sessionid =>
complete(s"session-id is: $sessionid")
}
} ~
path("session-cookie-age") {
solutionAge.shopperCookieAge { sessionid =>
complete(s"session-id is: $sessionid")
}
} ~
path("session-cookie-npe") {
ageUrsCombined.shopperCookieNPE { sessionid =>
complete(s"session-id is: $sessionid")
}
}
object solutionAge {
def shopperCookieAge: Directive1[HttpCookie] = existingShopperCookie | newUnregisteredShopperCookie
def setShopperCookie(cookie: HttpCookie): Directive1[HttpCookie] = {
setCookie(cookie) & provide(cookie)
}
private def existingShopperCookie: Directive1[HttpCookie] = {
cookie("session-id").flatMap { httpCookie ⇒
setShopperCookie(httpCookie)
}
}
private def newUnregisteredShopperCookie: Directive1[HttpCookie] = {
// I can't figure out a better way of providing a new value each and every time without
// forcing the route to be dynamic by wrapping it in this dummy provide
provide("dummy").flatMap { _ ⇒
setShopperCookie(HttpCookie("session-id", UUID.randomUUID().toString()))
}
}
}
object solutionUrs {
import shapeless._
val shopperCookieUrs: Directive1[HttpCookie] = optionalCookie("session-id").flatMap {
case Some(c) => provide(c)
case None => {
val sessionCookie = HttpCookie("session-id", UUID.randomUUID().toString())
liftToDirective1(setCookie(sessionCookie), sessionCookie)
}
}
private def liftToDirective1[T](f: Directive0, value: T): Directive1[T] = new Directive1[T] {
def happly(inner: T :: HNil ⇒ Route) = f(inner(value :: HNil))
}
}
object ageUrsCombined {
val shopperCookieNPE = cookie("session-id") | createCookieWithNPE
private val createCookieWithNPE: Directive1[HttpCookie] = {
val sessionCookie = HttpCookie("session-id", UUID.randomUUID().toString())
provide("dummy").flatMap { _ ⇒
setCookie(sessionCookie) & provide(sessionCookie)
}
}
}
}
object Boot extends App {
implicit val system = ActorSystem("hello-spray")
val restApi = system.actorOf(Props[GetOrCreateCookieSampleActor], "rest-api")
IO(Http) ! Bind(listener = restApi, interface = "0.0.0.0", port = 8080)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment