Akka Http-多路径和带隐式代码的简单体现

时间:2018-12-22 20:44:07

标签: scala akka akka-http spray

我有一个简单的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

但是此类(GameRoutingRateRouting)在构造函数中使用implicit,我不能简单地将这段代码移到单独的位置。 我应该如何重构此代码以获得我想要的?

我的另一个问题是-路由类(GameRoutingRateRouting)应该是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。

1 个答案:

答案 0 :(得分:1)

您可以将隐式对象移到单独的对象上

object GameAppImplicits {
  implicit val system = ActorSystem("game-service")
  implicit val materializer = ActorMaterializer()
  implicit val executionContext = system.dispatcher
}

,然后在需要时导入:

import yourpackage.GameAppImplicits._

对于第二个问题,案例类通常用于对不可变数据进行建模。在这种情况下,您实际上并不需要任何功能,而是需要案例类(例如自动toStringequalscopy等),因此我想最好只需使用普通的class