Play Controller如何实现双异步return?
How to achieve double asynchronous return from Play Controller?
我正在尝试编写一个异步 REST 方法,如下所示。
def createUser = Action.async(parse.json) { request =>
val b = request.body.validate[User]
b.fold(
errors => {
Future {
BadRequest(Json.obj("status" -> "OK", "message" -> JsError.toJson(errors)))
}
},
user => {
// I am stuck here! Looking the below you would
// understand what I need to do
// How to achieve this?
Future {
UserServiceImpl.createUser(user) onComplete {
case user => Ok
case _ => InternalServerError
}
}
)
}
问题是 Slick dbConfig.db.run 方法也是异步的。所以 UserServiceImpl.createUser 必须是异步的。
现在,如果 UserServiceImpl.createUser 抛出异常,我需要 return InternalServerError。如果成功,我想 return 好的。
我该怎么做?
下面是我的模型:
object User {
case class User(id: Long,
firstName: String,
lastName: String,
mobile: Long,
email: String)
implicit val userWrites = Json.writes[User]
implicit val userReads = Json.reads[User]
}
class UserTable(tag: Tag)
extends Table[User.User](tag, "user") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def firstName = column[String]("first_name")
def lastName = column[String]("last_name")
def mobile = column[Long]("mobile")
def email = column[String]("email")
override def * =
(id, firstName, lastName, mobile, email) <> (User.User.tupled, User.User.unapply)
}
以下是我的服务:
trait UserService {
def createUser(user: User): Future[User]
}
object UserServiceImpl extends UserService {
val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
val users = TableQuery[UserTable]
override def createUser(user: User): Future[User] = {
dbConfig.db.run(users += user).map(res => user)
}
}
自己找到解决方案:
def createUser = Action.async(parse.json) { request =>
val b = request.body.validate[User]
b.fold(
errors => {
Future {
BadRequest(Json.obj("status" -> "OK", "message" -> JsError.toJson(errors)))
}
},
user => {
UserServiceImpl.createUser(user).map(res => Ok) recover {
case ex: Exception => InternalServerError
}
}
)
}
我正在尝试编写一个异步 REST 方法,如下所示。
def createUser = Action.async(parse.json) { request =>
val b = request.body.validate[User]
b.fold(
errors => {
Future {
BadRequest(Json.obj("status" -> "OK", "message" -> JsError.toJson(errors)))
}
},
user => {
// I am stuck here! Looking the below you would
// understand what I need to do
// How to achieve this?
Future {
UserServiceImpl.createUser(user) onComplete {
case user => Ok
case _ => InternalServerError
}
}
)
}
问题是 Slick dbConfig.db.run 方法也是异步的。所以 UserServiceImpl.createUser 必须是异步的。
现在,如果 UserServiceImpl.createUser 抛出异常,我需要 return InternalServerError。如果成功,我想 return 好的。
我该怎么做?
下面是我的模型:
object User {
case class User(id: Long,
firstName: String,
lastName: String,
mobile: Long,
email: String)
implicit val userWrites = Json.writes[User]
implicit val userReads = Json.reads[User]
}
class UserTable(tag: Tag)
extends Table[User.User](tag, "user") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def firstName = column[String]("first_name")
def lastName = column[String]("last_name")
def mobile = column[Long]("mobile")
def email = column[String]("email")
override def * =
(id, firstName, lastName, mobile, email) <> (User.User.tupled, User.User.unapply)
}
以下是我的服务:
trait UserService {
def createUser(user: User): Future[User]
}
object UserServiceImpl extends UserService {
val dbConfig = DatabaseConfigProvider.get[JdbcProfile](Play.current)
val users = TableQuery[UserTable]
override def createUser(user: User): Future[User] = {
dbConfig.db.run(users += user).map(res => user)
}
}
自己找到解决方案:
def createUser = Action.async(parse.json) { request =>
val b = request.body.validate[User]
b.fold(
errors => {
Future {
BadRequest(Json.obj("status" -> "OK", "message" -> JsError.toJson(errors)))
}
},
user => {
UserServiceImpl.createUser(user).map(res => Ok) recover {
case ex: Exception => InternalServerError
}
}
)
}