我应该如何通过 DDD 将此值获取到 Akka HTTP 中的异步代码

How should I get this value through DDD to async code in Akka HTTP

我正在尝试使用域驱动设计编写一个 Akka HTTP 网络服务,但我正在努力将网络服务接收到的技术数据传递给在 Future 中执行工作的代码,即 correlationId 由客户端发送到我的网络服务。

我对 DDD 的理解是,作为实现的选择,correlationId 不应出现在域中:

package domain
trait MyRepository {
  def startWork(): Future[Unit]
}

为了让我的实现代码可以使用它而不是方法的参数,我正在考虑使用像 org.slf4j.MDCThreadLocal 这样的线程本地存储。但是,我不知道这是否可行,或者对 web 服务的多次调用是否会由同一个线程处理并覆盖该值。

实现如下:

package infra
class MyRepository(implicit executor: ExecutionContextExecutor) extends domain.MyRepository {
  override def startWork(): Future[Unit] = {
    Future {
      val correlationId = ??? // MDC.get("correlationId") ?
      log(s"The correlationId is $correlationId")
    }
  }
}

我的网络服务中的路由:

val repo = new infra.MyRepository()
val route = path("my" / "path") {
  post {
    parameter('correlationId) { correlationId =>
      ??? // MDC.put("correlationId", correlationId) ?
      onComplete(repo.startWork()) {
        complete(HttpResponse(StatusCodes.OK))
      }
    }
  }
}

我的问题是双重的:

Akka 中的本地线程(包括 MDC,尽管 Lightbend 订阅包括传播 MDC 以及消息和期货的工具)通常不是一个好主意,因为通常不能保证给定任务(Future在这种情况下,或处理已发送消息的参与者)将在与请求任务的线程相同的线程上执行(在特定情况下,该任务正在与外部 service/DB 执行 [可能阻塞] 交互(通过使用 Future {} 暗示),您几乎不希望这种情况发生)。此外,即使该任务最终在请求该任务的同一线程上执行,也不太可能没有其他可能改变 MDC/thread-local 的任务同时执行。

我自己认为将相关 ID 作为参数传递给 startWork 没有问题:您已经通过 HTTP 端点传递它来有效地公开它。