使用play和akka-https:如何正确地将多个请求链接到传入请求以创建响应?

时间:2016-02-26 19:50:50

标签: scala playframework-2.0 akka akka-stream akka-http

所以我试着让一个小游戏应用程序与另一个休息服务进行通信。 这个想法是,在播放方面接收请求,然后向其余的api请求并将结果的一部分提供给另一个本地演员,然后在浏览器中显示来自本地演员和其他服务的响应。 This image shows how

我尝试用流来做。我完成了所有工作,但我对我与当地演员交谈并创建Future[(Future[String],Future[String])元组的部分绝对不满意,所以如果你能指出我的方向我会很高兴,怎么做以优雅和干净的方式。

所以这是我的代码。输入是一个csv文件。 我的本地演员创建了一个我想要放入响应的附加图形。

def upload = Action.async(parse.multipartFormData) { request =>
 request.body.file("input").map { inputCsv =>

 //csv to list of strings
 val inputList: List[String] = convertFileToList(inputCsv)

 //http request to rest service
 val responseFuture: Future[HttpResponse] = httpRequest(inputList, "/path",4321 ,"0.0.0.0")

 //pattern match response and ask local actor
 val formattedResult = responseFuture.flatMap { response =>
  response.status match {
    case akka.http.scaladsl.model.StatusCodes.OK =>
      val resultTeams = Unmarshal(response.entity).to[CustomResultCaseClass]

     //the part I'd like to improve
      val tupleFuture = resultTeams.map(result => 
        (Future(result.teams.reduce(_ + "," + _)),
          plotter.ask(PlotData(result.eval)).mapTo[ChartPath].flatMap(plotAnswer => Future(plotAnswer.path))))
      tupleFuture.map(tuple => tuple._1.map(teams => 
        p._2.map(chartPath => Ok(views.html.upload(teams))(chartPath))))).flatMap(a => a).flatMap(b => b)
   }
 }
 formattedResult
}.getOrElse(Future(play.api.mvc.Results.BadRequest))
}

1 个答案:

答案 0 :(得分:0)

For comprehensions对此类用例很有用。一个演示重构的基本示例:

val teamFut = Future(result.teams.reduce(_ + "," + _))

//I think the final .flatMap(Future(_.path)) is unnecessary it should be
// .map(_.path), but I wanted to replicate the question code functionality
val pathFut = plotter.ask(PlotData(result.eval))
                     .mapTo[ChartPath]
                     .flatMap(Future(_.path))

val okFut = 
  for {
    teams     <- teamFut
    chartPath <- pathFut      
  } yield Ok(views.html.upload(teams))(chartPath)

注意:初始期货应该在实例之外进行实例化,否则不会发生并行执行。