我的登录端点大致与此类似
get {
(path("token") & parameters("email", "password")) { (email, password) =>
complete {
DBManager.getUserByEmail(email) match {
case Some(user) =>
// Check everything is return something
UserWire(user)
case None => StatusCodes.NotFound -> "User doesn't exist"
}
}
}
}
DBManager.getUserByEmail
返回Option[User]
。我刚刚切换到Slick,其中所有内容都是异步的,因此方法现在返回Future[User]
。
如果未来失败,我该如何发送所需的回复?我试过这个
complete {
DBManager.getUserByEmail(email).map(user => {
// Check everything is return something
UserWire(user)
}).recoverWith { case ex => Future.successful(StatusCodes.NotFound -> "User doesn't exist") }
}
无法使用
进行编译Error:(497, 26) type mismatch;
found : scala.concurrent.Future[Product with Serializable]
required: akka.http.scaladsl.marshalling.ToResponseMarshallable
}).recoverWith { case ex => Future.successful(StatusCodes.NotFound -> "User doesn't exist") }
^
我该如何解决?
答案 0 :(得分:4)
在喷涂中你可以使用onComplete
,它会得到一个未来并返回一个指令,所以在你的情况下:
onComplete(DBManager.getUserByEmail(email)) {
case Success(optUser) =>
complete {optUser.map(UserWire(_)).getOrElse(StatusCodes.NotFound -> "User doesn't exist") }
case Failure(_) =>
complete { InternalServerError() }
}
虽然我从未使用过,但似乎Akka http有same method。
答案 1 :(得分:1)
第一件事。在构建反应式应用程序时,最好只在成功的操作上运行。处理未来失败需要比成功运营更多的资源。 let long_circuit_or = (||);;
let print_true x = print_string x; true;;
(* just prints "4" *)
print_true "4" || print "5";;
(* prints "45" *)
long_circuit_or (print_true "4") (print_true "5");;
的反复版本应返回DBManager.getUserByEmail
当你将未来的地图结果带到Marshallable表格或回复时。
Future[Option[User]]