Skip to content

Instantly share code, notes, and snippets.

@danclien
Last active December 30, 2015 13:09
Show Gist options
  • Save danclien/7833643 to your computer and use it in GitHub Desktop.
Save danclien/7833643 to your computer and use it in GitHub Desktop.
Cleanest way I've found so far to divide Spray's routing into separate files.
/* Routing trait for mixing in routes */
trait RoutingService extends Directives { this: HttpServiceActor =>
private val EmptyRoute: Route = { context => Unit }
def routes: Route = EmptyRoute
/* Used to concatenate `Route`s together */
def concatRoutes(superRoutes: Route)(routes: Route): Route = superRoutes match {
case EmptyRoute => routes
case _ => superRoutes ~ routes
}
}
/* First set of routes */
trait Service1 extends RoutingService { this: HttpServiceActor =>
/* `super.routes` must be passed in for each Service trait */
override def routes = concatRoutes(super.routes) {
path("service1") {
complete {
"service1"
}
}
}
}
/* Second set of routes */
trait Service2 extends RoutingService { this: HttpServiceActor =>
override def routes = concatRoutes(super.routes) {
path("service2") {
complete {
"service2"
}
}
}
}
/* Root actor to handle incoming requests. Mixes in service traits to pull in `Route`s */
class RootService extends HttpServiceActor
with Service1
with Service2 {
val combinedRoutes = routes
def receive = runRoute(combinedRoutes)
}
/* `App` to bind HTTP to the `RootServer` actor */
object Main extends App {
implicit val system = ActorSystem("system")
val service = system.actorOf(Props[RootService], "root")
implicit val timeout = Timeout(5.seconds)
IO(Http) ? Http.Bind(service, interface = "localhost", port = 8080)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment