喷涂 REST API 应用程序结构 - 需要建议

Spray REST API Application Structure - Suggestions Needed

我有以下使用 sbt 构建的多模块项目结构:

myProject-api
myProject-core

myProject-core 组织如下:

它包含某些充当我服务门面的角色。例如,我有一个位于 UserService 前面的 UserActor。位于 NotificationService 前面的 NotificationActor 等等。

我还有另一个特点,可以让任何感兴趣的人看到演员:

trait MyProjectCoreActors {

  def myAppCfg = MyProjConfig.appCfg      

  def userActor = myAppCfg.userActor
  def notifyActor = myAppCfg.notifyActor
}
object MyProjectCoreActors {

  ... some initialization routing that initializes the MyProjConfig
}

我的 UserActor 定义为:

class UserActor(service: UserService) extends Actor {

  ...
  ...
}

我的UserService如下:

class UserService(dbConfig: DbConfig) {

  ...
  ...
}

我有另一个名为 MyProjectConfig 的 class,我使用 application.conf 文件对其进行了初始化。在这个文件中,我有数据库的连接细节等等。 MyProjectConfig 初始化如下:

trait MyProjectConfig {

  def actorSystem: ActorSystem

  // the actors
  def userActor: ActorRef
}
object MyProjectConfig {

  def apply(appConfig: Config, system: ActorSystem): MyProjectConfig = {

    new MyProjectConfig {
      private val dbConfig = loadDBConfig(appConfig)

      override val actorSystem = system

      // each actor gets its own DBConfigInstance instance
      override val userActor =
        actorSystem.actorOf(
          Props(new UserActor(UserService(dbConfig)))
        )
    }
  }
}

我现在有如下定义的喷雾路由:

trait MyProjectService extends HttpService with MyProjectCoreActors {

  def pingRoute = path("ping") {
    get {
      userActor ! "newUser"
      complete("pong!")
    }
  }

  def pongRoute = path("pong") {
    get { complete("pong!?") }
  }

  def route = pingRoute ~ pongRoute
}

现在缺少的是调用MyProjectConfig.apply(....)方法并传入Actor System和底层application.conf的方法!

这最初是一个基于 Play 的应用程序,我有一个 Lifecycle 插件,它可以访问底层应用程序,我从那里获得了配置和演员系统。我现在如何使用 Spray 获得相同的效果?

我的靴子 class 看起来像这样:

object MyBootHttpService extends App {

  implicit val actorSystem = ActorSystem("myproj-actor-system")

}

如何将这个 ActorSytem 传递给 MyProjectConfig.apply(....)?我从哪里可以得到 application.conf?

我认为你可以在 MyBootHttpService class 中做这样的事情 (DI)。

例如

object MyBootHttpService extends App {

  implicit val actorSystem = ActorSystem("myproj-actor-system")
  private val config = ConfigFactory.load
  private val myAppConfig = MyProjectConfig(config, actorSystem)

  // Initialise classes that depend on config and actorsystem....
  private val service = new MyProjectService with HttpServiceActor {
     override implicit val actorRefFactory = actorSystem
  }
  // Bind our service
  IO(Http) ? Bind(listener = service, interface = "0.0.0.0", port = config.getInt("port"))

}

Typesafe 配置库对象ConfigFactory 通常用于加载配置文件。没有参数的 ConfigFactory.load 将尝试从 class 路径加载 application.conf