对服务的多次休息调用
Multiple rest calls to a service
我必须对服务进行多次 REST 调用才能获取有关多个资源的信息。一旦所有资源信息可用,我就需要以某种方式加入它们。
你能给我指出正确的 Scala/play 构造来做到这一点吗?
Future
composition via for-comprehension:
for {
sugar <- getSugar
lemons <- getLemons
lemonJuice <- pressLemons(lemons)
water <- getWater
} yield {
makeLemonade(sugar, lemonJuice, water)
}
Daniel Westheide 在这方面做得很好tutorial。
对于 Play
上的 REST 客户端功能,Play WS doc. You can chain your REST calls and process corresponding responses using a for-comprehension
like in the following example, borrowed from this Play WS section 中有相当详细的文档:
val futureResponse: Future[WSResponse] = for {
responseOne <- ws.url(urlOne).get()
responseTwo <- ws.url(responseOne.body).get()
responseThree <- ws.url(responseTwo.body).get()
} yield responseThree
futureResponse.recover {
case e: Exception =>
val exceptionData = Map("error" -> Seq(e.getMessage))
ws.url(exceptionUrl).post(exceptionData)
}
Leo 和 Mario 的解释已经足够了,但是如果你想要更高性能和并行的 运行ning 代码,你可以参考下面的代码片段:
def prepareCappuccino(): Future[Cappuccino] = {
val groundCoffee = ws.url("url1").get()
val heatedWater = ws.url("url2").get()
val frothedMilk = ws.url("url3").get()
for {
ground <- groundCoffee
water <- heatedWater
foam <- frothedMilk
espresso <- brew(ground, water)
} yield combine(espresso, foam)
}
像这样定义您的未来调用可以使每个未来调用在并行线程中异步执行,并且它将 运行 大约 n-times
更快地进行 n 次调用,而不是直接在 for 中使用您的调用理解。
发生这种情况是因为为了理解 de-sugars 嵌套的平面地图和地图调用以及形成的管道导致阻塞和同步 API 调用,如果您不这样做,scala 必须按原样解释它们不要事先定义你的未来。
Here 是 Linked-in 团队负责 play 框架开发的一篇有趣的文章。
关于网络客户端的使用,您可以在官方中轻松查找documentation。
我必须对服务进行多次 REST 调用才能获取有关多个资源的信息。一旦所有资源信息可用,我就需要以某种方式加入它们。
你能给我指出正确的 Scala/play 构造来做到这一点吗?
Future
composition via for-comprehension:
for {
sugar <- getSugar
lemons <- getLemons
lemonJuice <- pressLemons(lemons)
water <- getWater
} yield {
makeLemonade(sugar, lemonJuice, water)
}
Daniel Westheide 在这方面做得很好tutorial。
对于 Play
上的 REST 客户端功能,Play WS doc. You can chain your REST calls and process corresponding responses using a for-comprehension
like in the following example, borrowed from this Play WS section 中有相当详细的文档:
val futureResponse: Future[WSResponse] = for {
responseOne <- ws.url(urlOne).get()
responseTwo <- ws.url(responseOne.body).get()
responseThree <- ws.url(responseTwo.body).get()
} yield responseThree
futureResponse.recover {
case e: Exception =>
val exceptionData = Map("error" -> Seq(e.getMessage))
ws.url(exceptionUrl).post(exceptionData)
}
Leo 和 Mario 的解释已经足够了,但是如果你想要更高性能和并行的 运行ning 代码,你可以参考下面的代码片段:
def prepareCappuccino(): Future[Cappuccino] = {
val groundCoffee = ws.url("url1").get()
val heatedWater = ws.url("url2").get()
val frothedMilk = ws.url("url3").get()
for {
ground <- groundCoffee
water <- heatedWater
foam <- frothedMilk
espresso <- brew(ground, water)
} yield combine(espresso, foam)
}
像这样定义您的未来调用可以使每个未来调用在并行线程中异步执行,并且它将 运行 大约 n-times
更快地进行 n 次调用,而不是直接在 for 中使用您的调用理解。
发生这种情况是因为为了理解 de-sugars 嵌套的平面地图和地图调用以及形成的管道导致阻塞和同步 API 调用,如果您不这样做,scala 必须按原样解释它们不要事先定义你的未来。
Here 是 Linked-in 团队负责 play 框架开发的一篇有趣的文章。
关于网络客户端的使用,您可以在官方中轻松查找documentation。