Вы захотите что-то вроде этого:
def a: Action[AnyContent] = Action.async { _ =>
b("hello").map(s => Ok(s))
}
def b(y: String): Future[String] = {
ws.url(url).post(y).flatMap { response =>
if (response.body == "hi") Future.successful(response.body) else c(response.body)
}
}
def c(z: String): Future[String] = {
ws.url(url).post(z).map { response =>
response.body
}
}
Несколько вещей.
1) Тип вашего метода a
будет Action[AnyContent]
, так как вы создаете Play Action
. Обычно люди опускают тип методов действия и позволяют компилятору выяснить это. Обратите внимание, что если ваше действие более сложное (например, оно читает тело запроса JSON), то его тип может быть Action[something_else]
(например, Action[JsValue]
, если вы используете Play Json).
2) Поскольку b
возвращает будущее, вам необходимо создать Action
, используя Action.async
, который принимает функцию типа Request => Future[Response]
(до того, как вы вызвали Action.apply
, которая принимает функцию типа Request => Response
).
3) В A
необходимо map
от String
в Future
до Response
; Я делаю это, используя Ok
(т. Е. HTTP 200), хотя, конечно, вы можете использовать все, что подходит.
4) В b
, flatMap
- ваш друг, потому что c
возвращает Future[String]
, и, таким образом, вы получаете Future[Future[String]]
, когда используете map
... flatMap
, чтобы сгладить это до Future[String]
.
5) Вам нужно обернуть первую ветвь вашего оператора if
в Future.successful
, чтобы обе ветви возвращали один и тот же тип Future[String]
. Future.successful
просто строит Future
, который уже завершен.
6) Наконец, вам не нужно объявлять значения x
, y
и z
; каждое выражение соответствует своему значению, которое действительно приводит в порядок вещи.