Как связать будущие клиентские запросы без вложенности с помощью onComplete?

Мне нужно запросить RESTful-сервис, который всегда возвращает JSON-ответ. Мне нужно связаться с ним несколько раз, всегда с дополнительной информацией, которую я узнал из предыдущего запроса. Я использую 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 ответа

Решение

HttpDialog, кажется, точно охватывает ваш случай использования.

Я думаю, что нашел разумный ярлык, используя 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

}

Если это наилучший доступный подход, я отмечу его как "отвеченный", но мне не терпится получить реальные ответы от людей, которые знают этот материал намного лучше меня.

Другие вопросы по тегам