具有scala未来的Akka http路由

Akka http route with scala future

情况是这样

// validateRoute act like a directive which validate a route before proceeding further
override def validateRoute(route: Route)(implicit ec: ExecutionContext): Route = {
  extractRequest { request =>
    decodeRequest {
      entity(as[String]) { content =>
        (headerValueByName("header1") & headerValueByName("header2")) {
          case (header1, header2) => {
            // dom some
            // validate() returns a Future[Either[Error, Boolean]]
            validate().map {
              result => {
                result match {
                  case Right(_) => route
                  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
                }
              }
            }
          } // I get a error here saying It expect route whereas it is Future[Route]
        }
      }
    }
  }
}

我收到上述错误,而且我无法更改 return 类型的 validate () ,有没有办法解决这个问题。我需要一种方法 return 路由而不是 Future[Route]

如果您注册了 handleRejections 指令,则可以在 Future 上使用 onSuccess 指令:

onSuccess(validate()) {
  case Right(_) => route
  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
}

否则你可以使用 onComplete 指令,你必须匹配 SuccessFailure

如果你必须使用 return 路线而不是 Future[Route],你可以尝试使用

Await.result(validate(), Duration(2, TimeUnit.SECONDS)) //substitute your choice of duration

这将阻塞直到验证 returns.

所以完整的解决方案看起来像,

// validateRoute act like a directive which validate a route before proceeding further
override def validateRoute(route: Route)(implicit ec: ExecutionContext): Route = {
  extractRequest { request =>
    decodeRequest {
      entity(as[String]) { content =>
        (headerValueByName("header1") & headerValueByName("header2")) {
          case (header1, header2) => {
            // dom some
            // validate() returns a Future[Either[Error, Boolean]]
            Await.result(validate(),Duration(2, TimeUnit.SECONDS) ) match 
                {
                  case Right(_) => route
                  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
                }
          }  
        }
      }
    }
  }
}