1 2 3 4 5 | def findPublications(query: String): Future[AuthorPublications] = for { authorId <- findAuthor(query) (author, pubs) <- getAuthor(authorId) product getPublications(authorId) } yield AuthorPublications(author, pubs) |
1 2 3 | sealed trait ServiceError case object InvalidQuery extends ServiceError case object NotFound extends ServiceError |
1 2 3 4 5 6 | def findAuthor(query: String): Future[Either[ServiceError, Long]] = Future.successful( if (query == "matthias k") 42L.asRight else if (query.isEmpty) InvalidQuery.asLeft else NotFound.asLeft ) |
findAuthor("matthias k") map { idOrError => idOrError map { id => ...} } |
1 2 3 4 5 | // bind Future and SearchError together while leaving the inner result type unbound type Result[A] = EitherT[Future, SearchError, A] // this allows you to invoke the companion object as "Result" val Result = EitherT |
1 2 3 4 | def findAuthor(query: String): Result[Long] = if (query == "matthias k") Result.rightT(42L) else if (query.isEmpty) Result.leftT(InvalidQuery) else Result.leftT(NotFound) |
1 2 3 4 5 6 7 | def getAuthor(id: Long): Result[Author] = Result.rightT(Author(id, "Matthias Käppler")) def getPublications(authorId: Long): Result[List[Publication]] = Result.rightT(List( Publication(1L, authorId, "Model-First Microservices with Scala & Cats") )) |
1 2 3 4 5 6 | def findPublications(query: String): Result[AuthorPublications] = for { authorId <- findAuthor(query) result <- getAuthor(authorId) product getPublications(authorId) (author, pubs) = result } yield AuthorPublications(author, pubs) |
1 2 3 4 5 6 7 8 9 | val query = "matthias k" val search: Result[Unit] = findPublications(query) map { authorPubs => renderResponse(200, s"Found $authorPubs") } recover { case InvalidQuery => renderResponse(400, s"Not a valid query: '$query'") case NotFound => renderResponse(404, s"No results found for '$query'") } Await.result(search.value, Duration.Inf) |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |