2016-01-26 49 views
2

我正在嘗試編寫如下的異步REST方法。如何從Play控制器實現雙重異步返回?

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

問題是滑動dbConfig.db.run方法也是異步的。所以UserServiceImpl.createUser必須是異步的。

現在,如果UserServiceImpl.createUser引發異常,我需要返回InternalServerError。如果成功,我想返回Ok。

我該怎麼做?

下面是我的模型:

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

} 

回答

2

找到自己的解決方案:

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

您應該使用Future.successful。請參閱http://stackoverflow.com/a/21466781 – danielnixon