У нас есть приложение Scala/Play, в котором у нас есть несколько неявных классов, которые создают объекты Try из запроса, например.Составление нескольких объектов Try в Scala/Play
implicit class RequestUtils[+T](req: Request[T]) {
def user: Try[User] = // pull the User from the Session, or throw an UnauthorizedException
def paging: Try[Paging] = // create a Paging object, or throw an IllegalArgumentException
}
Затем доступ обернутые объекты через flatMaps
def route(pathParam: String) = BasicAction {
request =>
request.user.flatMap(user =>
request.paging.flatMap(paging =>
Try{ ... }
))}
И, наконец, ActionBuilder Формирует SimpleResult из Попробуйте
case class BasicRequest[A](request: Request[A]) extends WrappedRequest(request)
class BasicActionBuilder extends ActionBuilder[BasicRequest] {
def invokeBlock[A](request: Request[A], block: (BasicRequest[A]) => Future[SimpleResult]) = {
block(BasicRequest(request))
}
}
def BasicAction[T](block: BasicRequest[AnyContent] => Try[T]) = {
val f: BasicRequest[AnyContent] => SimpleResult = (req: BasicRequest[AnyContent]) =>
block(req) match {
case Success(s) => Ok(convertToJson(s))
case Failure(e: UnauthorizedException) => Unauthorized(e.getMessage)
case Failure(e: Exception) => BadRequest(e.getMessage)
case Failure(t: Throwable) => InternalServerError(e.getMessage)
}
val ab = new BasicActionBuilder
ab.apply(f)
}
Мы пытаемся найти способ, по существу, составьте несколько объектов Try вместе (или что-то в этих строках - мы не привязаны к использованию Trys) - flatMaps работают нормально для одного или двух Trys, но вложение их больше, чем это затрудняет программу читаемость. Мы можем вручную компоновать объекты вместе, например.
case class UserAndPaging(user: User, paging: Paging)
implicit class UserAndPagingUtils[+T](req: Request[T]) {
def userAndPaging: Try[UserAndPaging] = req.user.flatMap(user => req.paging.flatMap(paging => UserAndPaging(user, paging))
}
, но это приведет к взрыву классов класса case-неявного класса def. В идеале я хотел бы объединять несколько объектов Try совместно специальным способом, например.
def route(pathParam: String) = BasicAction {
request => compose(request.user, request.paging).flatMap(userWithPaging => ...)
}
и попробовать [Пользователь с Paging] волшебно составленную для меня, но я понятия не имею, как бы я идти об этом - я боролся с системой типа, чтобы попытаться присвоить значимое типа, чтобы «составить» без каких-либо успехов.
Как я могу скомпоновать несколько объектов Try или что-то эквивалентное с помощью конструкции другого языка?
... и не забывайте о том, что 'Future [T]' по существу 'Попробуйте [T]', что hasn Мы закончили еще - мы приняли решение о том, что все наши вызовы на уровне обслуживания возвращают Futures, и это было здорово. Вы получаете все, что «для» -добавления дополнений, плюс он прекрасно вписывается в асинхронную поддержку Play. Даже если конкретная услуга не обязательно должна быть асинхронной, так легко переносить результат в 'Future.successful()', вы также можете! :-) – millhouse