Scala 在没有全局HttpContext的另一个逻辑层中记录用户活动

Scala 在没有全局HttpContext的另一个逻辑层中记录用户活动,scala,playframework,functional-programming,cross-cutting-concerns,Scala,Playframework,Functional Programming,Cross Cutting Concerns,我正在寻找一个好的解决方案来记录使用Play/Scala/ReactiveMongo开发的web应用程序中的DB更改。我需要知道是谁改变了什么 我有一个单独的层,即所有数据访问和业务逻辑发生的服务。所有保存/更新/删除都是通过某些方法完成的,因此我可以用3或4种方法安全地记录它们,但我需要用户标识 我无法访问服务中的当前用户!没有全局HttpContext或请求或类似的东西可以让我获得用户身份,我认为这种获得用户身份的方式当然是不正确的 我有一个解决办法: 将隐式参数添加到具有副作用的所有服务方

我正在寻找一个好的解决方案来记录使用Play/Scala/ReactiveMongo开发的web应用程序中的DB更改。我需要知道是谁改变了什么

我有一个单独的层,即所有数据访问和业务逻辑发生的服务。所有保存/更新/删除都是通过某些方法完成的,因此我可以用3或4种方法安全地记录它们,但我需要用户标识

我无法访问服务中的当前用户!没有全局HttpContext或请求或类似的东西可以让我获得用户身份,我认为这种获得用户身份的方式当然是不正确的

我有一个解决办法:

将隐式参数添加到具有副作用的所有服务方法中,以更改数据库并将用户标识传递给它们

def save(model: A)(implicit userIdentity: Option[UserIndentity] = None) = { ... }
当我包装默认请求时,它可以扩展UserIdentity特性,以便隐式请求与隐式参数匹配

class MyRequest[A](...) extends WrappedRequest[A](request) extends UserIdentity
最后,操作可以使用如下服务:

def index() = MyAction { implicit request =>
    //...
    defaultService.save(model)
    //...
}

糟糕的是,我必须向这些服务方法添加隐式参数。没有其他解决方案可以在不污染方法签名的情况下获取当前用户。

简单地将UserIdentity作为参数添加到函数中有什么问题?知道用户是谁似乎对您的业务逻辑很重要——毕竟,今天您要记录谁执行了操作,明天您要确保允许该特定用户执行操作


我只需要使用一个真正的UserIdentity对象,而不是WrappedRequest的黑客攻击,您的服务不需要与WrappedRequest实例混淆。

您可以使用线程局部变量,也许可以利用scala.util.DynamicVariable,但只有在同一个线程中完成所有操作时才有效,没有未来,等等。,我的应用程序是完全异步的,所以我不能使用线程本地解决方案。所以它应该传递给每一个使签名难以写入或读取的方法。