Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Last active August 29, 2015 14:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j5ik2o/37a09ccaea7e02860eeb to your computer and use it in GitHub Desktop.
Save j5ik2o/37a09ccaea7e02860eeb to your computer and use it in GitHub Desktop.
spray-routingをベースしたControllerの書き方
import akka.actor._
import akka.io.IO
import spray.can.Http
import spray.routing.{Directives, HttpService, RequestContext, Route}
trait Action {
def apply(request: RequestContext): Unit
}
object Action {
def apply(block: RequestContext => Unit) = new Action {
override def apply(ctx: RequestContext): Unit = block(ctx)
}
}
trait ControllerSupport extends Directives {
protected def getQueryParam(key: String)(implicit ctx: RequestContext): Option[String] =
ctx.request.uri.query.get(key)
}
// ほんとはこのアプリケーションサービス内でドメインモデルとファクトリ、リポジトリが登場するが、サンプルなので省略している。
case class FactApplicationService {
def fact(n: Seq[Long]): Seq[Future[Long]] = {
Future.traversal(n) { n =>
fact(n)
}
}
private def fact(n: Long): Long = {
def fact0(result: Long, n: Long): Long =
n match {
case 0 => result
case _ => fact0(n * result, n - 1)
}
fact(1, n)
}
}
case class FactController(factApplicationService: FactApplicationService) extends ControllerSupport {
def fact = Action { implicit ctx =>
val values: Seq[Int] = getQueryParam("values")
.map(s => s.split(",")
.map(_.toInt).toSeq)
.getOrElse((1 to 10).toSeq)
val future: Future[Seq[Int]] =
Future.sequence(factApplicationService.fact(values))
val results: Seq[Int] = Await.result(future, Duration.Inf)
ctx.complete(s"results = $results")
}
}
trait Routes extends HttpService with ControllerSupport {
val factController = FactController()
protected val routes: Route = {
get {
path("fact") { ctx =>
factController.fact(ctx)
}
}
}
}
class ServiceActor extends Actor with Routes {
def actorRefFactory = context
def receive = runRoute(routes)
}
object Main extends App {
implicit val system = ActorSystem()
val handler = system.actorOf(Props[ServiceActor], name = "handler")
IO(Http) ! Http.Bind(handler, interface = "localhost", port = 8080)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment