我正在努力将应用程序从Spray.io迁移到Akka-http . 该应用程序是基于微服务的,具有许多我们构建的小型库 . 以下是在一个特定的微服务中编写指令和路由的示例:
val routes =
(decompressRequest & compressResponseIfRequested) {
metricsRoute ~
healthStatusRoute ~
apiRoutes // only these are my app's routes
}
除了 apiRoutes
之外,所有上述内容都在内部库中定义 .
我想在这个微服务中开始使用Akka-http(将 apiRoutes
迁移到Akka-http),而不更改我当前使用的任何库,因为这会迫使所有其他开发人员同时更改其代码 .
这可能吗?有没有办法让Akka-http使用Spray.io指令/路由?
据我所知,migration guide没有这样的信息 .
1 回答
这并不难做到 . 如您所知,Spray中的
Route
是RequestContext ⇒ Unit
,Akka中的Route
是RequestContext ⇒ Future[RouteResult]
(当然,它们各自的版本为RequestContext
) . 我所做的是创建一个包装器,它可以包装一个Spray路由,通过Spray服务actor提供这种转换 . 路线是单独包裹的,然后根据需要折叠~
完整的顶级Akka路线 . 然后,随着时间的推移转换是逐个删除包装器直到所有路径都已转换的过程 .由于您要转换为Akka,请从Akka HTTP套接字处理程序和折叠结果开始 . 现在,您将添加包裹的Spray路线到该折叠 .
对于它来说,未转换的Spray指令想要响应一个Actor,所以你的包装器为被包装的路由创建一个服务actor . 这个actor对Akka的呈现很简单:一个带
RequestContext
并返回Future[RouteResult]
的函数与服务actor上的ask()
相同,并带有一条返回RouteResult
的消息(由ActorSystem
方便地包装在Future
中) . 排除Actor,这个包装器大约有十行代码 .服务参与者本身扩展Spray
HttpServiceActor
并接受一条消息,即AkkaRequestContext
. 此消息被机械转换为SprayRequestContext
,处理所需的任何使用模式 . 该消息处理程序的最后一行是self ! ctx
,将已翻译的上下文发送到超类中的SprayHttpServiceActor
处理程序 .返回Akka的结果是通过发送给Spray的
RequestContext
上的withRouteResponseMapped()
. 您传递的函数反向,将Spray构造映射回Akka并返回RouteResult
. 如果你只是做HttpEntity.Strict
返回值,这非常简单 .我希望我可以在这里发布代码,但它是为客户编写的,他们对IP共享有未知(但显然是严格的)限制 .