在akka http上创建一个包含60+ API的REST Web服务。如何选择是否应该选择akka流或akka演员? 在他的post中,乔显示了两种在akka http上创建API的方法,但是他没有显示何时应该选择其中一种。
答案 0 :(得分:21)
这是一个棘手的问题。显然,这两种方法都有效。所以在某种程度上这是一个品味/熟悉的问题。所以现在所关注的一切只是我个人的意见。
如果可能的话,我更喜欢使用akka-stream,因为它具有更高级别的性质和类型安全性。但这是否可行,很大程度上取决于REST API的任务。
如果您的REST API是一项服务,例如根据外部数据(例如货币兑换率API)回答问题,最好使用akka-stream实现。
另一个优选akka-stream的例子是某种数据库前端,其中REST API的任务是解析查询参数,将它们转换为数据库查询,执行查询并根据内容翻译结果 - 用户请求的类型。在这两种情况下,数据流都可以轻松映射到akka-stream原语。
如果您的API允许查询和更新群集上的多个持久性actor,则可能更喜欢使用actor的示例。在这种情况下,基于纯粹的基于actor的解决方案或混合解决方案(使用akka-stream解析查询参数和翻译结果,使用actor执行其余操作)可能更可取。
另一个基于actor的解决方案可能更受欢迎的例子是,如果您有长期运行请求的REST API(例如websockets),并希望在群集上部署REST API本身的处理管道。我认为目前使用akka-stream 所有是不可能的。
总结一下:查看每个API的数据流,看看它是否干净地映射到akka-stream提供的原语。如果是这种情况,请使用akka-stream实现它。否则,使用actor或混合解决方案实现。
答案 1 :(得分:9)
我对Rudiger Klaehn的一个好的答案是,还要考虑Future
的用例。期货的可组合性和F
的资源管理使期货成为许多(如果不是大多数)情况的理想选择。
有一个很好的blog post描述Futures比Actors更好的选择。此外,Streams提供的背压带来了一些非常沉重的overhead。
仅仅因为你使用akka-http击倒了兔子洞并不意味着请求处理程序中的所有并发都必须限制在Actors或Streams中。
<强>路线强>
ExecutionContext
固有地容纳type definition中的期货:
Route
因此,您只需使用函数和期货,无需指令即可将Future直接烘焙到您的Route中:
type Route = (RequestContext) ⇒ Future[RouteResult]
onComplete Directive
onComplete
指令允许您在路线中“展开”未来:
val requestHandler : RequestContext => HttpResponse = ???
val route : Route =
(requestContext) => Future(requestHandler(requestContext)) map RouteResult.Complete