Reputation: 23
I have 3 methods: a, b, and c. Method a has some logic and it calls method b. Method b makes an api call returning Future[String]. If the returned value from method b is a certain value, method c is called. Method c makes another api call returning another Future[String].
def a: String = Action { request =>
val x = b("hello")
x
}
def b(y: String): Future[String] = {
val x = ws.url(url).post(y).map { response =>
val value = response.body
val z = if (response.body === "hi") response.body else c(response.body)
z
}
x
}
def c(z: String): Future[String] = {
val x = ws.url(url).post(z).map { response =>
response.body
}
x
}
Something like the code above. Eventually I want to parse everything into a json object, but I'm having trouble getting the Futures as regular strings. I'm new to scala and would appreciate some input.
Upvotes: 0
Views: 341
Reputation: 2582
You'll want something like this:
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
}
}
A few things.
1) The type of your method a
will be an Action[AnyContent]
, since you are creating a Play Action
. It's common to see people omit the type of action methods and let the compiler figure it out. Note if your action is more sophisticated (e.g. it reads a JSON request body) then its type might be Action[something_else]
(e.g. Action[JsValue]
if you're using Play Json).
2) Because b
returns a future, you need to create the Action
using Action.async
which takes a function of type Request => Future[Response]
(before you were calling Action.apply
which takes a function of type Request => Response
).
3) In A
, you need to map
the String
in the Future
to a Response
; I do this using Ok
(i.e. HTTP 200), although of course you can use whatever's appropriate.
4) In b
, flatMap
is your friend, because c
returns a Future[String]
and thus you end up with a Future[Future[String]]
when you use map
... flatMap
flattens that to a Future[String]
.
5) You need to wrap the first branch of your if
statement in Future.successful
, such that both branches return the same type, Future[String]
. Future.successful
just builds a Future
that is already completed.
6) Finally, you don't need to declare values x
, y
and z
; each expression resolves to its value, which really tidies things up.
Upvotes: 1