Подтвердить что ты не робот

Как я могу использовать будущее в директиве Akka HTTP?

В настоящее время у меня есть директива, которую я использую для защиты ресурсов в приложении 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, который возвращает запрос.

Ни один из примеров Directive1, которые поставляются с Akka HTTP, похоже, не делает этого (по крайней мере, я мог бы найти его), хотя есть примеры директив, возвращающих Route, которые делают.

Я хочу сделать то, что я хочу сделать? Является ли возможным подход для создания подкласса StandardRoute с полем для учетных данных пользователя и как-то возвращаться?

4b9b3361

Ответ 1

Да, это возможно. Насколько я понимаю, вам нужно что-то вроде этого:

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)
  }
}