Tengo una función que recupera datos de DB y devuelve el tipo de Future [ResponseDTO], luego necesito convertirlo a Future of HttpResponse

Mi código:

val responseDTO = database.getResponseDto(service) => Future[ResponseDTO]

responseDTO.onComplete {
   case Success(responseDTO) => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload)
   case Failure(exception) => HttpError("error")
}

No va a funcionar

Probó esta también, todavía no funciona

responseDTO.map(
  dto => EitherT.pure[Future, HttpError](HttpResponse(status = dto.responseCode, entity = dto.responsePayload))
)
4
user468587 11 may. 2019 a las 02:39

4 respuestas

La mejor respuesta

Quieres mapear el futuro. El método .onComplete no transforma el futuro, solo agrega un controlador (útil para los efectos secundarios)

responseDTO.map(dto => HttpResponse(status=dto.responseCode, entity=dto.responsePayload))
3
pedrorijo91 11 may. 2019 a las 07:16

El uso de transform debería dar la respuesta que desea:

responseDTO.transform {
  case Success(responseDTO) => Success(HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload))
  case _ => Success(HttpError("error"))
}

Esto devolverá un Future exitoso cuyo tipo de resultado es compatible con HttpResponse y HttpError.

Si desea conservar la información sobre el éxito / el fracaso, es mejor hacerlo utilizando el estado de Future. En ese caso, su código usaría una versión alternativa de transform, como esta:

case class HttpErrorException(err: HttpError) extends Throwable

responseDTO.transform(
  responseDTO => HttpResponse(status = responseDTO.responseCode, entity = responseDTO.responsePayload),
  _ => HttpErrorException(HttpError("error"))
)

Luego puede usar los métodos Future en el resto del código para extraer HttpResponse o HttpErrorException cuando sea necesario.

5
Tim 11 may. 2019 a las 09:25

Debe usar .map para mapear un cómputo futuro exitoso, use .recover para mapear una excepción durante el cómputo futuro y Either para obtener un resultado exitoso / fallido.

    val responseDTO: Future[ResponseDTO] = ... 

    val future: Future[Either[HttpError, HttpResponse]] = 
      responseDTO
        .map(d => Right(HttpResponse(status = d.responseCode, entity = d.responsePayload)))
        .recover {
          case t: Throwable => Left(HttpError("error"))
        }

Si sus clases tienen una superclase, digamos:

trait Http

case class HttpResponse(...) extends Http

case class HttpError(...) extends Http

Puedes evitar usar Either:

    val future: Future[Http] =
      responseDTO
        .map(d => HttpResponse(status = d.responseCode, entity = d.responsePayload))
        .recover {
          case t: Throwable => HttpError("error")
        }
3
Matthew I. 11 may. 2019 a las 12:25

Lo que debe hacer es asignar su futuro anterior de tipo A a un nuevo futuro de tipo B, el método onComplete del futuro tiene efectos secundarios y simplemente ayuda a adjuntar devoluciones de llamada a los resultados y su firma de método devuelve la Unidad.

-1
awesome_cos 11 may. 2019 a las 11:52