如何在不使用onComplete嵌套的情况下链接Future的客户端请求?

时间:2012-08-18 08:33:46

标签: scala spray

我需要查询始终返回JSON响应的RESTful服务。我需要与它联系几次,总是提供一些我从之前的请求中学到的更多信息。我正在使用Akka2,Scala,Jerkson和Spray-Can。

我目前的方法似乎有效,但看起来很难看,需要嵌套一切。我读到应该有一些关于链接的技术,但是我无法弄清楚如何将它们应用到我当前的用例中。

这是我正在谈论的代码:

def discoverInitialConfig(hostname: String, bucket: String) = {

    val poolResponse: Future[HttpResponse] = 
      HttpDialog(httpClient, hostname, 8091)
      .send(HttpRequest(uri = "/pools"))
      .end

    poolResponse onComplete { 
      case Right(response) =>
        log.debug("Received the following global pools config: {}", response)

        val pool = parse[PoolsConfig](response.bodyAsString)
          .pools
          .find(_("name") == defaultPoolname)
          .get

        val selectedPoolResponse: Future[HttpResponse] =
          HttpDialog(httpClient, hostname, 8091)
          .send(HttpRequest(uri = pool("uri")))
          .end

        selectedPoolResponse onComplete {
          case Right(response) =>
            log.debug("Received the following pool config: {}", response)

            println(response.bodyAsString)

          case Left(failure) =>
            log.error("Could not load the pool config! {}", failure)
        }

      case Left(failure) =>
        log.error("Could not load the global pools config! {}", failure)
    }

我认为你可以看到这种模式。联系REST服务,阅读它,成功时将其解析为JSON案例类,提取信息然后进行下一次调用。

我的结构只有两层深,但我还需要添加第三层。

是否有一种技术可以改善这一点以提高可读性,或者我是否只能坚持这一点?如果您需要任何进一步的信息,我很乐意提供。您可以在此处查看完整代码:https://github.com/daschl/cachakka/blob/f969d1f56a4c90a929de9c7ed4e4a0cccea5ba70/src/main/scala/com/cachakka/cluster/actors/InitialConfigLoader.scala

谢谢, 迈克尔

2 个答案:

答案 0 :(得分:2)

HttpDialog似乎完全涵盖了您的用例。

答案 1 :(得分:0)

我认为通过使用spray-can提供的reply方法找到了合理的捷径。

def discoverInitialConfig(hostname: String, bucket: String) = {

val poolResponse: Future[HttpResponse] = 
  HttpDialog(httpClient, hostname, 8091)
  .send(HttpRequest(uri = "/pools"))
  .reply(response => {
    log.debug("Received the following global pools config: {}", response)
    val selectedPool = parse[PoolsConfig](response.bodyAsString)
      .pools.find(_("name") == defaultPoolname).get
    HttpRequest(uri = selectedPool("uri"))
  })
  .reply(response => {
    log.debug("Received the following pool config: {}", response)
    println(response.bodyAsString)
    HttpRequest(uri = "/")
  })
  .end

}

如果这是最好的方法,我会将其标记为“已回答”,但我很想得到比我更了解这些内容的人的实际回复。