Skip to content

Instantly share code, notes, and snippets.

@4lex1v
Created February 16, 2016 14:27
Show Gist options
  • Save 4lex1v/d190805cf9cc578bdf86 to your computer and use it in GitHub Desktop.
Save 4lex1v/d190805cf9cc578bdf86 to your computer and use it in GitHub Desktop.
Code for the article
/**
* For simplity i'm using Ammonite-Repl.
* https://lihaoyi.github.io/Ammonite/
*/
// Add Spray repo resolver
import ammonite.repl._, Resolvers._
resolvers() = resolvers() :+ Resolver.Http("spray repo", "http://repo.spray.io", IvyPattern, false)
// Load toolkit
load.ivy("io.spray" %% "spray-routing" % "1.3.3")
load.ivy("io.spray" %% "spray-json" % "1.3.2")
// Wrapped into object to paste it into
// Ammonite repl.
object code {
import scala.concurrent._, ExecutionContext.Implicits._
import spray.json._, DefaultJsonProtocol._
import spray.routing._, Directives._
import spray.httpx.SprayJsonSupport._
final case class RegistrationData(login: String, pwd: String)
object RegistrationData {
implicit val format = jsonFormat2(RegistrationData.apply)
}
final case class Account(data: RegistrationData)
case object MalformedRegistrationDataRej extends Rejection
type ID = String
def validate(data: RegistrationData): Option[RegistrationData] = ???
def storeAccountInDB(acc: Account): Future[ID] = ???
val registerRoute = {
path("register") {
post {
entity(as[RegistrationData]) { entity =>
validate(entity) match {
case None => reject(MalformedRegistrationDataRej)
case Some(data) =>
val account = Account(data)
val res = storeAccountInDB(account)
onSuccess(res) { id =>
complete(s"Your new id is $id!")
}
}
}
}
}
}
val registrationEndpoint: Directive1[RegistrationData] =
path("register") & post & entity(as[RegistrationData])
val registerRouteImp = {
registrationEndpoint { entity =>
validate(entity) match {
case None => reject(MalformedRegistrationDataRej)
case Some(data) =>
val account = Account(data)
val res = storeAccountInDB(account)
onSuccess(res) { id =>
complete(s"Your new id is $id!")
}
}
}
}
def validateDir(user: RegistrationData): Directive0 = {
if (user.pwd.nonEmpty) pass
else reject(MalformedRegistrationDataRej)
}
def createAccount(data: RegistrationData): Directive1[Account] = {
provide(Account(data))
}
def persist(account: Account): Directive1[ID] = {
onSuccess(storeAccountInDB(account))
}
val registerRouteOpt = {
registrationEndpoint { entity =>
validateDir(entity) {
createAccount(entity) { acc =>
persist(acc) { id =>
complete(s"Your new id is $id!")
}
}
}
}
}
def withNewAccount(entity: RegistrationData): Directive1[ID] = {
validateDir(entity) & createAccount(entity).flatMap(persist)
}
load.ivy("org.scalaz" %% "scalaz-core" % "7.2.0")
import scalaz.Monad
implicit val directive1Monad = new Monad[Directive1] {
def point[A](a: ⇒ A): Directive1[A] = provide(a)
def bind[A, B](fa: Directive1[A])(f: (A) ⇒ Directive1[B]): Directive1[B] = fa.flatMap(f)
}
import shapeless._
implicit def dir02dir1(dir0: Directive0): Directive1[HNil] = dir0.hflatMap(_ => provide(HNil))
import scalaz.syntax.monad._
val data: Directive[String :: String :: HNil] = hprovide("4lex1v" :: "scala" :: HNil)
data.as(RegistrationData.apply _) >>= withNewAccount
}
import code._
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment