将路由从 spray.io 迁移到 akka http

Migrating routes from spray.io to akka http

我正在努力将应用程序从 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 directives/routes 吗?

据我所知,migration guide 没有此类信息。

这并不难做到。如您所知,Spray 中的 RouteRequestContext ⇒ Unit,Akka 中的 RouteRequestContext ⇒ Future[RouteResult](当然,它们各自的版本是 RequestContext)。我所做的是创建一个可以包装 Spray 路由的包装器,以通过 Spray 服务参与者提供这种转换。路由被单独包装,然后根据需要用 ~ 折叠以获得完整的顶级 Akka 路由。随着时间的推移,转换是一个一个地移除包装器的过程,直到所有路由都被转换。

由于您正在将 转换为 Akka,因此请从 Akka HTTP 套接字处理程序和折叠结果开始。现在您要将包装的 Spray 路线添加到该折叠。

就其本身而言,未转换的 Spray 指令想要响应一个 Actor,因此您的包装器会为被包装的路由创建一个服务 actor。将此 actor 呈现给 Akka 很简单:接受 RequestContext 和 return 的函数和 Future[RouteResult] 与服务 actor 上的 ask() 相同,消息为returns a RouteResult(方便地用 ActorSystem 包装在 Future 中)。不包括 Actor,这个包装器大约有十行代码。

服务参与者本身扩展了 Spray HttpServiceActor 并接受一条消息,这是一条 Akka RequestContext。此消息被机械地转换为 Spray RequestContext,处理所需的任何使用模式。该消息处理程序的最后一行是 self ! ctx,将翻译后的上下文发送到超类中的 Spray HttpServiceActor 处理程序。

返回 Akka 的结果是通过发送到 Spray 的 RequestContext 上的 withRouteResponseMapped()。您传递的函数执行相反的操作,将 Spray 构造映射回 Akka 并 returning a RouteResult。如果你只是做 HttpEntity.Strict return 值,这非常简单。

我希望我可以 post 这里的代码,但它是为客户编写的,他们对 IP 共享有未知的(但显然是严格的)限制。