user3543006
user3543006

Reputation: 83

How can I pass an Array of RedisFutures to Akka HTTP onSuccess method?

I have a function in my EmployeesRepository class with the following signature:

def findAllEmployeesById(ids: List[String]): Array[RedisFuture[String]] {...}

I am basically trying to pass this to an EmployeeREST class which has a GET method that takes in a List[String] (the employee ids) and is supposed to return a JSON array of corresponding employees retrieved from Redis.

Am I allowed to pass in an Array[RedisFuture[String]]? Is there a way for me to actually implement this or am I thinking about it the wrong way? Is there a different way to achieve the functionality I'm trying to implement here?

Upvotes: 1

Views: 476

Answers (1)

Extending some of the comments to the question: you can first convert your RedisFuture to a scala Future using the converter:

import scala.compat.java8.FutureConverters.toScala

val redisFutureToScalaFuture : RedisFuture[String] => Future[String] = toScala

This can be used to convert the entire RedisFuture Array:

val redisArrayToScala : Array[RedisFuture[String]] => Array[Future[String]] = 
  _ map redisFutureToScalaFuture

Now, the Future.sequence function will be handy to unwrap the Futures inside of the Array:

val unwrapArray : Array[Future[String]] => Future[Array[String]] = Future.sequence 

Combine all of these together along with the original query function:

val idsToFuture : List[String] => Future[Array[String]] = 
  (findAllEmployeesById _) andThen redisArrayToScala andThen unwrapArray

Finally, the idsToFuture can be used within a Directive:

val entityToList : RequestEntity => List[String] = ???

val arrayToResponse : Array[String] => String = ???

val route : Route = 
  get {
    extractRequestEntity { entity =>
      onComplete(idsToFuture(entityToList(entity))) {
        case Success(arr) => complete(200 -> arrayToResponse(arr))
        case Failure(ex)  => complete(500 -> ex.toString)
      }
    }
  }

Upvotes: 2

Related Questions