Arjun Karnwal
Arjun Karnwal

Reputation: 379

Akka http route with scala future

Here is the situation

// validateRoute act like a directive which validate a route before proceeding further
override def validateRoute(route: Route)(implicit ec: ExecutionContext): Route = {
  extractRequest { request =>
    decodeRequest {
      entity(as[String]) { content =>
        (headerValueByName("header1") & headerValueByName("header2")) {
          case (header1, header2) => {
            // dom some
            // validate() returns a Future[Either[Error, Boolean]]
            validate().map {
              result => {
                result match {
                  case Right(_) => route
                  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
                }
              }
            }
          } // I get a error here saying It expect route whereas it is Future[Route]
        }
      }
    }
  }
}

I get the above mentioned error, also I can not change the return type of validate () , is there a way to fix this issue. I need a way to return route instead of Future[Route]

Upvotes: 0

Views: 387

Answers (2)

samizzy
samizzy

Reputation: 88

If you HAVE to return route instead of Future[Route], you can try using

Await.result(validate(), Duration(2, TimeUnit.SECONDS)) //substitute your choice of duration

this will block till validate returns.

So the full solution will look like,

// validateRoute act like a directive which validate a route before proceeding further
override def validateRoute(route: Route)(implicit ec: ExecutionContext): Route = {
  extractRequest { request =>
    decodeRequest {
      entity(as[String]) { content =>
        (headerValueByName("header1") & headerValueByName("header2")) {
          case (header1, header2) => {
            // dom some
            // validate() returns a Future[Either[Error, Boolean]]
            Await.result(validate(),Duration(2, TimeUnit.SECONDS) ) match 
                {
                  case Right(_) => route
                  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
                }
          }  
        }
      }
    }
  }
}

Upvotes: -1

1565986223
1565986223

Reputation: 6718

If you've a handleRejections directive registered, you can use the onSuccess directive on Future:

onSuccess(validate()) {
  case Right(_) => route
  case Left(ex) => complete(StatusCodes.Unauthorized -> ex.getMessage)
}

Else you can use onComplete directive and you'll have to match Success and Failure

Upvotes: 2

Related Questions