Use of Await in Controller

am I doing right things

val delay = 10 seconds
def createHome(id: UUID): Action[JsValue] =
    Action(parse.json) { implicit request =>

      request.body.validate[HomeData] match {
        case JsSuccess(data, _) =>
          val userId = UUID.randomUUID() // this is come from token
         if(Await.result(userapiService.checkPermission(userId,id,"Creation").invoke,delay )){
             if(Await.result(userapiService.checkQuota(id,"check").invoke,delay )){
                Ok("do what ever you want to do")

              }else Unauthorized("you should recharge your plan")
          }else Unauthorized("you don't have permission to create ")

        case _ => BadRequest("some thing went wrong check your request first")
      }
    }

You should avoid the use of Await in Play controllers, as it will block the calling thread and reduce the efficiency of the server, which is designed for non-blocking I/O. Instead, you can use an asynchronous action builder and compose the futures:

https://www.playframework.com/documentation/2.7.x/ScalaAsync

https://docs.scala-lang.org/overviews/core/futures.html

I haven’t tested this code, but it would look something like this:

def createHome(id: UUID): Action[JsValue] =
    Action.async(parse.json) { implicit request =>
      request.body.validate[HomeData] match {
        case JsSuccess(data, _) =>
          val userId = UUID.randomUUID() // this is come from token
          userapiService.checkPermission(userId,id,"Creation").invoke.flatMap { hasPermission =>
            if (hasPermission) {
              userapiService.checkQuota(id,"check").invoke.map { withinQuota =>
              if (withinQuota) {
                Ok("do what ever you want to do")
              } else Unauthorized("you should recharge your plan")
            } else Future.successful(Unauthorized("you don't have permission to create "))
          }
        case _ => Future.successful(BadRequest("some thing went wrong check your request first"))
      }
    }

It would be more readable with some additional refactoring to split it up into multiple methods, but hopefully the main idea comes across: prefer flatMap and map over Await.result.

1 Like