【问题标题】:play framework 2.5 move Action.async logic from controller to serviceplay framework 2.5 将 Action.async 逻辑从控制器移动到服务
【发布时间】:2017-03-09 12:42:59
【问题描述】:

我有一个包含许多业务逻辑的控制器,我想将代码移动到 Action.async 代码块中。此代码有效,如何将 Action.async 内部的代码移至另一个类(服务)?:

def tweetsnew(query: String) = Action.async {
// Move From Here...
credentials.map {
  case (consumerKey, requestToken) =>
    ws.url("https://api.twitter.com/1.1/search/tweets.json")
      .sign(OAuthCalculator(consumerKey, requestToken))
      .withQueryString("q" -> query)
      .withQueryString("max_id" -> "833342796736167936")
      .get().map { twitterResponse =>
      if (twitterResponse.status == 200) {
        // Here There Are More Complex Logic
        Ok("That is fine: "+twitterResponse.body)
      } else {
        throw new Exception(s"Could not retrieve tweets for $query query term")
      }
    }
}.getOrElse {
  Future.failed(new Exception("You did not correctly configure the Twitter credentials"))
}
//....To Here. To Another Class
}

我已经检查了与 create a Future[Result] 相关的文档,但我无法确定该函数返回的类型与 Action.async 期望的类型相同。

【问题讨论】:

  • 感谢@vdebegue,这是一个很好的解决方案。我想提出另一种解决方案。

标签: scala asynchronous playframework controller playframework-2.5


【解决方案1】:

Action.async 期望返回类型为 Future[Result],因此您需要创建一个返回 Future[Result] 的函数

第一步,将代码提取到函数中:

object TwitterService {
  def search(query: String, consumerKey: ConsumerKey, requestToken: RequestToken)(implicit ws: WSClient, ec: ExecutionContext): Future[Result] = {
    // your code that make the ws call that returns Ok("...")
  }
 }

然后在控制器中调用你的函数:

def tweetsnew(query: String) = Action.async {
  credentials.map {
    case (consumerKey, requestToken) => TwitterService.search(query, consumerKey, requestToken)
  }.getOrElse {
    // Better to send a bad request or a redirect instead of an Exception
    Future.successful(BadRequest("Credentials not set"))
  }
}

【讨论】:

  • 谢谢@vdebegue。我想提出另一种解决方案。要在服务中创建这样的特征:@ImplementedBy(classOf[TwitterFeed]) trait QueryTweets { def queryByWord(query: String): Future[Option[JsValue]] } 2) 在服务中实现特征,相同的文件:class TwitterFeed @Inject() extends QueryTweets { // A complex code Json.parse("""{"changeByObject":"yes"}""") Some(aJsonResponse) } 3) 在控制器中:def tweetsnew(query: String) = Action.async { queryTweets.queryByWord(query).flatMap{ case Some(response) => { Future.successful(Ok(response)) } } }
  • 这也有效,这取决于您何时更愿意将依赖项注入WSClientExecutionContext。你的方式更“java-ish”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多