Scala Akka Http API单例用户上下文

Scala Akka Http API单例用户上下文,scala,akka,akka-http,Scala,Akka,Akka Http,我正在使用Scala和Akka Http编写RESTAPI 对于请求处理,我以RequestContext=>Future[RouteResult] 在每个路由中,我必须将用户的上下文从一个函数传递到另一个函数,这有点麻烦。例如,在下面的代码中,我总是必须将userContext传递到与数据库交互的每个函数中 val route: Route = { requestContext => { val userContext = extractUser(request

我正在使用Scala和Akka Http编写RESTAPI

对于请求处理,我以
RequestContext=>Future[RouteResult]

在每个路由中,我必须将用户的上下文从一个函数传递到另一个函数,这有点麻烦。例如,在下面的代码中,我总是必须将
userContext
传递到与数据库交互的每个函数中

val route: Route = {    
   requestContext => {
      val userContext = extractUser(requestContext)
      val computeResult = compute(userContext)
      requestContext.complete(computeResult)   
   } 
}
但是,如果我将上下文设置为singleton,那么当下一个调用进入时,它就有被重写的风险,因为API是多租户的


有没有更好的方法来处理这个问题?

给读者一个机会。这将允许您对用户上下文进行更好的抽象

这可能是一个近似:

import scala.concurrent.Future
import scala.util.{Failure, Success}
import scalaz.{Reader, ReaderT}

trait UserContext {
  val user: String
  val passwd: String
}

trait YourDBFunctionsII[T] {
  def compute(): Reader[UserContext, T]
  def computeII(): Reader[UserContext, T]
}

object YourDBFunctionsII extends YourDBFunctionsII[String] {
  override def compute(): Reader[UserContext, String] = Reader {
    in: UserContext =>
      ???
  }

  override def computeII(): Reader[UserContext, String] = Reader {
    in: UserContext =>
      ???
  }
}

class YourRoutesII {
  import YourDBFunctionsII._

  val route: Route = { requestContext =>
    {
      val userContext: UserContext = ??? // Extract from RequestContext

      val routines = for {
        resul1 <- compute()
        resul2 <- computeII()
      } yield resul2

      // Execute monad composition
      val computeResult = routines.run(userContext)

      requestContext.complete(computeResult)
    }
  }
}
导入scala.concurrent.Future
导入scala.util.{失败,成功}
导入scalaz.{Reader,ReaderT}
特征用户上下文{
val用户:字符串
val passwd:String
}
特征函数i[T]{
def compute():读取器[UserContext,T]
def computeII():读取器[UserContext,T]
}
对象YourDBFunctionsII扩展了YourDBFunctionsII[字符串]{
重写def compute():读卡器[UserContext,String]=读卡器{
in:UserContext=>
???
}
重写def computeII():读卡器[UserContext,String]=读卡器{
in:UserContext=>
???
}
}
给你的路线分类{
导入您的DBFunctionsII_
val路由:路由={requestContext=>
{
val userContext:userContext=???//从RequestContext提取
val例程=用于{
结果1
“错误”
}
}
重写def computeII():ReaderT[Future,UserContext,String]=ReaderT{
ctx=>
未来{
//做其他事情
ctx.passwd
}
}
}
第二类{
导入您的DBFunctionsII_
val路由:路由={requestContext=>
{
val userContext:userContext=???//从RequestContext提取
val例程=用于{

结果1为读者Monad提供了一个机会。这将允许您对用户上下文进行更好的抽象

这可能是一个近似:

import scala.concurrent.Future
import scala.util.{Failure, Success}
import scalaz.{Reader, ReaderT}

trait UserContext {
  val user: String
  val passwd: String
}

trait YourDBFunctionsII[T] {
  def compute(): Reader[UserContext, T]
  def computeII(): Reader[UserContext, T]
}

object YourDBFunctionsII extends YourDBFunctionsII[String] {
  override def compute(): Reader[UserContext, String] = Reader {
    in: UserContext =>
      ???
  }

  override def computeII(): Reader[UserContext, String] = Reader {
    in: UserContext =>
      ???
  }
}

class YourRoutesII {
  import YourDBFunctionsII._

  val route: Route = { requestContext =>
    {
      val userContext: UserContext = ??? // Extract from RequestContext

      val routines = for {
        resul1 <- compute()
        resul2 <- computeII()
      } yield resul2

      // Execute monad composition
      val computeResult = routines.run(userContext)

      requestContext.complete(computeResult)
    }
  }
}
导入scala.concurrent.Future
导入scala.util.{失败,成功}
导入scalaz.{Reader,ReaderT}
特征用户上下文{
val用户:字符串
val passwd:String
}
特征函数i[T]{
def compute():读取器[UserContext,T]
def computeII():读取器[UserContext,T]
}
对象YourDBFunctionsII扩展了YourDBFunctionsII[字符串]{
重写def compute():读卡器[UserContext,String]=读卡器{
in:UserContext=>
???
}
重写def computeII():读卡器[UserContext,String]=读卡器{
in:UserContext=>
???
}
}
给你的路线分类{
导入您的DBFunctionsII_
val路由:路由={requestContext=>
{
val userContext:userContext=???//从RequestContext提取
val例程=用于{
结果1
“错误”
}
}
重写def computeII():ReaderT[Future,UserContext,String]=ReaderT{
ctx=>
未来{
//做其他事情
ctx.passwd
}
}
}
第二类{
导入您的DBFunctionsII_
val路由:路由={requestContext=>
{
val userContext:userContext=???//从RequestContext提取
val例程=用于{

结果1你能发布你的代码吗?添加了一些示例代码你可以使上下文隐式,但我个人认为你的代码不好是的
compute
函数有很多层,每个层都需要传递
userContext
。我喜欢隐式的想法。你能发布你的代码吗?添加了一些示例代码你可以d使上下文隐式,但我个人认为您的代码不好。
compute
函数有许多层,每个层都需要传入
userContext
。不过我喜欢隐式的想法。