我有一个简单的Main
对象,它通过以下方式为我的两个服务创建了routes
:
object GameApp extends App {
val config = ConfigFactory.load()
val host = config.getString("http.host")
val port = config.getInt("http.port")
implicit val system = ActorSystem("game-service")
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
val game = new GameRouting
val rate = new RateRouting
val routes: Route = game.route ~ rate.route
Http().bindAndHandle(routes, host, port) map {
binding => println(s"Server start on ${binding.localAddress}")
} recover {
case ex => println(s"Server could not start on ${host}:${port}", ex.getMessage)
}
}
现在,我想重构这段代码并将其移到单独的方法/类/对象等中。
val game = new GameRouting
val rate = new RateRouting
val routes: Route = game.route ~ rate.route
但是此类(GameRouting
和RateRouting
)在构造函数中使用implicit
,我不能简单地将这段代码移到单独的位置。
我应该如何重构此代码以获得我想要的?
我的另一个问题是-路由类(GameRouting
和RateRouting
)应该是class
还是case class
?这是GameRouting
类:
trait Protocols extends SprayJsonSupport with DefaultJsonProtocol {
implicit val gameFormat = jsonFormat4(Game)
}
class GameRouting(implicit executionContext: ExecutionContext) extends Protocols {
val gameService = new GameService
val route: Route = {
pathPrefix("games") {
pathEndOrSingleSlash {
get {
complete {
gameService.getGames()
}
} ~
post {
entity(as[Game]) { gameForCreate =>
createGame(gameForCreate)
}
}
} ~
pathPrefix(LongNumber) { id =>
get {
complete {
gameService.getGame(id)
}
} ~ put {
entity(as[Game]) { gameForUpdate =>
complete {
gameService.update(gameForUpdate)
}
}
}
}
}
}
private def createGame(gameForCreate: Game) = {
onComplete(gameService.createGame(gameForCreate)) {
case Success(created) => complete(StatusCodes.Created, created)
case Failure(exception) => complete(StatusCodes.BadRequest, s"An error: $exception")
}
}
}
如果我将其设置为case
,则无法访问routes
对象中的字段Main
。如何解决此问题或以更好的方式编写它?也许有一些基本问题,但是从几周以来我一直在学习Scala和Akka。
答案 0 :(得分:1)
您可以将隐式对象移到单独的对象上
object GameAppImplicits {
implicit val system = ActorSystem("game-service")
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
}
,然后在需要时导入:
import yourpackage.GameAppImplicits._
对于第二个问题,案例类通常用于对不可变数据进行建模。在这种情况下,您实际上并不需要任何功能,而是需要案例类(例如自动toString
,equals
,copy
等),因此我想最好只需使用普通的class
。