加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 以功能方式进行多个API调用

发布时间:2020-12-16 19:11:36 所属栏目:安全 来源:网络整理
导读:通过使用 Scala和Cats(或者可能是另一个专注于类别理论和/或函数式编程的库),以最具功能性(代数)的方式解决这个问题的最佳方法是什么? 资源 如果我们有以下方法执行REST API调用来检索单个信息? type FutureApiCallResult[A] = Future[Either[String,Optio
通过使用 Scala和Cats(或者可能是另一个专注于类别理论和/或函数式编程的库),以最具功能性(代数)的方式解决这个问题的最佳方法是什么?

资源

如果我们有以下方法执行REST API调用来检索单个信息?

type FutureApiCallResult[A] = Future[Either[String,Option[A]]]

def getNameApiCall(id: Int): FutureApiCallResult[String]
def getAgeApiCall(id: Int): FutureApiCallResult[Int]
def getEmailApiCall(id: Int): FutureApiCallResult[String]

如您所见,它们会产生异步结果. Either monad用于在API调用期间返回可能的错误,而Option用于在API未找到资源时返回None(这种情况不是错误,而是可能的和期望的结果类型).

以功能方式实现的方法

case class Person(name: String,age: Int,email: String)

def getPerson(id: Int): Future[Option[Person]] = ???

如果任何API调用失败或任何API调用返回None(整个Person实体无法组合),则此方法应使用上面定义的三个API调用方法异步组合并返回Person或None.

要求

出于性能原因,所有API调用必须以并行方式完成

我猜

我认为最好的选择是使用Cats Semigroupal Validated但是在尝试处理Future和如此多的嵌套Monads时我迷路了:S

任何人都可以告诉我你将如何实现这一点(即使改变方法签名或主要概念)或指向我正确的资源?我在编码时对Cats和Algebra很新,但我想学习如何处理这种情况,以便我可以在工作中使用它.

解决方法

您可以使用cats.Parallel类型类.这使得一些非常整洁的组合器具有EitherT,当并行运行时会累积误差.因此,最简单,最简洁的解决方案是:

type FutureResult[A] = EitherT[Future,NonEmptyList[String],Option[A]]

def getPerson(id: Int): FutureResult[Person] = 
  (getNameApiCall(id),getAgeApiCall(id),getEmailApiCall(id))
    .parMapN((name,age,email) => (name,email).mapN(Person))

有关Parallel的更多信息,请访问cats documentation.

编辑:这是没有内部选项的另一种方式:

type FutureResult[A] = EitherT[Future,A]

def getPerson(id: Int): FutureResult[Person] = 
  (getNameApiCall(id),getEmailApiCall(id))
    .parMapN(Person)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读