【问题标题】:Migrating routes from spray.io to akka http将路由从 spray.io 迁移到 akka http
【发布时间】:2024-01-03 12:51:01
【问题描述】:

我正在将应用程序从 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 没有此类信息。

【问题讨论】:

    标签: scala akka spray akka-http


    【解决方案1】:

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

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

    就其本身而言,未转换的 Spray 指令想要响应 Actor,因此您的包装器会为被包装的路由创建一个服务 Actor。这个actor向Akka的展示很简单:一个接受RequestContext并返回Future[RouteResult]的函数与服务actor上的ask()相同,带有返回RouteResult的消息(方便地包装在FutureActorSystem)。不包括 Actor,这个包装器大约有十行代码。

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

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

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

    【讨论】: