如何在 Akka HTTP 指令中使用 Future?
How can I use a Future inside an Akka HTTP Directive?
我目前有一个指令用于保护 Akka HTTP 应用程序中的资源,如下所示:
def authenticate: Directive1[Login] =
optionalHeaderValueByName("Authorization") flatMap {
val accessToken = authz.split(' ').last
case Some(authz) =>
LoggedInUser findByAccessToken accessToken match {
case Some(user) => provide(user)
case None => reject(AuthorizationFailedRejection)
}
case None => reject(AuthorizationFailedRejection)
}
其中 LoggedInUser.findByAccessToken()
对数据库进行阻塞查询,我想将异步 ask
切换为可以提供相同数据的参与者,我可以通过在 ActorRef
中作为指令的参数,但我不知道如何处理 Future
请求 returns.
Akka HTTP 附带的 Directive1
示例中的 None 似乎是这样做的(至少我找不到),尽管有指令示例 returning Route
哪个做的。
我想做的事有可能吗?是否有一种可能的方法来创建一个 StandardRoute
子类,其中包含一个用于用户凭据的字段并且 return 不知何故?
是的,这是可能的。据我了解,您需要这样的东西:
def authenticate: Directive1[Login] = {
def findByAccessToken(accessToken:String): Future[Option[Login]] = ???
optionalHeaderValueByName("Authorization").flatMap {
case Some(authz) =>
val accessToken = authz.split(' ').last
onSuccess(findByAccessToken(accessToken)).flatMap {
case Some(user) => provide(user)
case None => reject(AuthorizationFailedRejection)
}
case None => reject(AuthorizationFailedRejection)
}
}
我目前有一个指令用于保护 Akka HTTP 应用程序中的资源,如下所示:
def authenticate: Directive1[Login] =
optionalHeaderValueByName("Authorization") flatMap {
val accessToken = authz.split(' ').last
case Some(authz) =>
LoggedInUser findByAccessToken accessToken match {
case Some(user) => provide(user)
case None => reject(AuthorizationFailedRejection)
}
case None => reject(AuthorizationFailedRejection)
}
其中 LoggedInUser.findByAccessToken()
对数据库进行阻塞查询,我想将异步 ask
切换为可以提供相同数据的参与者,我可以通过在 ActorRef
中作为指令的参数,但我不知道如何处理 Future
请求 returns.
Directive1
示例中的 None 似乎是这样做的(至少我找不到),尽管有指令示例 returning Route
哪个做的。
我想做的事有可能吗?是否有一种可能的方法来创建一个 StandardRoute
子类,其中包含一个用于用户凭据的字段并且 return 不知何故?
是的,这是可能的。据我了解,您需要这样的东西:
def authenticate: Directive1[Login] = {
def findByAccessToken(accessToken:String): Future[Option[Login]] = ???
optionalHeaderValueByName("Authorization").flatMap {
case Some(authz) =>
val accessToken = authz.split(' ').last
onSuccess(findByAccessToken(accessToken)).flatMap {
case Some(user) => provide(user)
case None => reject(AuthorizationFailedRejection)
}
case None => reject(AuthorizationFailedRejection)
}
}