1

我的登录端点看起来大致像这样

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

我该如何解决?

4

2 回答 2

4

In spray you can use onComplete, it gets a future and returns a directive, so in your case:

onComplete(DBManager.getUserByEmail(email)) {
  case Success(optUser) =>
    complete {optUser.map(UserWire(_)).getOrElse(StatusCodes.NotFound -> "User doesn't exist") }
  case Failure(_) =>
    complete { InternalServerError() }
}

Although I've never used it seems like Akka http has the same method.

于 2015-12-23T11:38:40.243 回答
1

第一件事。当您构建反应式应用程序时,最好只对成功的操作进行操作。处理未来的失败比成功的操作需要更多的资源。DBManager.getUserByEmail应该返回的反应版本Future[Option[User]]

当您有未来时,只需将结果映射到 Marshallable 表单或响应。

get {
  (path("token") & parameters("email", "password")) { (email, password) =>
    complete {
      DBManager.getUserByEmail(email) map {
        case Some(user) =>
          UserWire(user)
        case None => 
          StatusCodes.NotFound -> "User doesn't exist"
      }
    }
  }
}
于 2015-12-23T21:57:01.537 回答