akka-http with multiple route configurations

el n00b picture el n00b · Dec 29, 2015 · Viewed 11.1k times · Source

Quick Background

I am running through some examples learning the Akka HTTP stack for creating a new REST project (completely non-UI). I have been using and augmenting the Akka HTTP Microservice Example to work through a bunch of use cases and configurations and have been pleasantly surprised by how well Scala & Akka HTTP work.

Current Setup

Currently I have a configuration like this:

object AkkaHttpMicroservice extends App with Service {
  override implicit val system = ActorSystem()
  override implicit val executor = system.dispatcher
  override implicit val materializer = ActorMaterializer()

  override val config = ConfigFactory.load()
  override val logger = Logging(system, getClass)

  Http().bindAndHandle(routes, config.getString("http.interface"), config.getInt("http.port"))
}

The routes parameter is just a simple value that has the typical data within it using path, pathPrefix, etc.

The Problem

Is there any way to set up routing in multiple Scala files or an example somewhere out there?

I would really like to be able to define a set of classes that separate the concerns and deal with Actor setup and processing to deal with different areas of the application and just leave the marshaling to the root App extension.

This might be me thinking too much in terms of how I did things in Java using annotations like @javax.ws.rs.Path("/whatever") on my classes. If that is the case, please feel free to point out the change in mindset.

I tried searching for a few different set of keywords but believe I am asking the wrong question (eg, 1, 2).

Answer

mgosk picture mgosk · Dec 29, 2015

Problem 1 - combine routes in multiple files

You can combine routes from multiple files quite easy.

FooRouter.scala

object FooRouter {
   val route = path("foo") {
       complete {
          Ok -> "foo"
       } 
   }       
}

BarRouter.scala

object BarRouter {
   val route = path("bar") {
       complete {
          Ok -> "bar"
       } 
   }       
}

MainRouter.scala

import FooRouter
import BarRouter
import akka.http.scaladsl.server.Directives._
import ...

object MainRouter {
   val routes = FooRouter.route ~ BarRouter.route
}

object AkkaHttpMicroservice extends App with Service {
  ...    
  Http().bindAndHandle(MainRouter.routes, config.getString("http.interface"), config.getInt("http.port"))
}

Here you have have some docs :

Problem 2 - seprate routing, marshalling, etc

Yes, you can separate routing, marshalling and application logic. Here you have activator example: https://github.com/theiterators/reactive-microservices

Problem 3 - handle routes using annotations

I don't know any lib that allow you to use annotion to define routing in akka-http. Try to learn more about DSL routing. This represents a different approach to http routing but it is convenient tool too.