Scala Akka Http API单例用户上下文
我正在使用Scala和Akka Http编写RESTAPI 对于请求处理,我以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
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
。不过我喜欢隐式的想法。