溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

STTP的基本使用方法是什么

發(fā)布時(shí)間:2021-12-27 15:52:23 來源:億速云 閱讀:241 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容介紹了“STTP的基本使用方法是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

如果使用 AkkaHttp 作為 STTP 的 backend 來并發(fā)地處理 list of url,就會(huì)得到類似 List[Future[Response[Either[ResponseError[io.circe.Error], T]]]],這樣的結(jié)果。

一般地,我們更期望給上層調(diào)用者返回 Future[(List[Exception], List[T])]這樣的類型。

下面代碼演示了如何把:

List[Future[Response[Either[ResponseError[io.circe.Error], NasaData]]]]

準(zhǔn)換為

Future[(List[Throwable], List[NasaData])]。

其中 tuple 的第一部分表示 response 中所有的 exception,第二部分表示所有正常數(shù)據(jù)。

幾個(gè)技術(shù)關(guān)鍵點(diǎn)是:

1)Future.sequence 用于把 List[Future] 轉(zhuǎn)為 Future[List]。

2)忽略 STTP Response 里除去 body 數(shù)據(jù)的其它部分,并把 response 轉(zhuǎn)為 Either[Throwable, NasaData]。

3)經(jīng)過步驟 1,2,數(shù)據(jù)類型已經(jīng)是 Future[List[Either[Throwable, NasaData]]]。

4)List[Either[Throwable, NasaData]] 轉(zhuǎn)為 (List[Throwable], List[NasaData])的思路是:

a) 構(gòu)造一個(gè)空的 Tuple (List[Throwable(), List[NasaData]())作為一個(gè)累計(jì)器。

b) 使用 List.folderLeft()遍歷元素,根據(jù)是 left 還是 right 累加到累計(jì)器的_1 或_2。

下面鏈接的文章演示了兩種轉(zhuǎn)換方式,一種是 Scala 原生手寫,一種是使用 CAT。

但是,其中語句 case Left(err) => acc.left.map(_ => err) 的邏輯似乎與期望不符。如果 list of either 中有 Left,并不能工作。

  val erA: Either[String, Int] = Right(1)  val erB: Either[String, Int] = Right(2)  val erC: Either[String, Int] = Right(3)  val elA: Either[String, Int] = Left("error1")  val elB: Either[String, Int] = Left("error2")  val listOfEither = List(erA, elA, erB, erC, elB)  private val eitherOfList: Either[String, List[Int]] = listOfEither.foldLeft(Right[String, List[Int]](List()).asInstanceOf[Either[String, List[Int]]])((acc, elem) => {    elem match {      case Right(v) => acc.map(l => l :+ v)      case Left(e) => acc.left.map(_ + e)    }  })  println(s"eitherOfList: $eitherOfList")

輸出如下,并沒有error部分的信息。

eitherOfList: Right(List(1, 2, 3))

下面的代碼演示了并發(fā)發(fā)出100個(gè)RestAPi請求獲取數(shù)據(jù)的處理代碼,結(jié)果保存在Tuple里,分別是所有失敗和成功的數(shù)據(jù)。

  import io.circe.generic.auto._  import sttp.client._  import sttp.client.akkahttp.AkkaHttpBackend  import sttp.client.circe._
 import scala.concurrent.Future  import scala.concurrent.duration._  import scala.concurrent.Await  import scala.concurrent.ExecutionContext.Implicits.global
 val NASA_API_KEY = "XXXXXXXXXXXXXXX"  val baseUrl = s"https://api.nasa.gov/neo/rest/v1/neo/browse?api_key=${NASA_API_KEY}"
 var pageSize = 10  var pageNumb = 100
  case class Links(self: String, next: String)  case class Page(number: Int, size: Int, total_elements: Int, total_pages: Int)  case class NearEarthObject(absolute_magnitude_h: Double, designation: String)  case class NasaData(links: Links, page: Page, near_earth_objects: List[NearEarthObject])
  implicit val sttpBackend = AkkaHttpBackend()    val listOfFutureResult: List[Future[Response[Either[ResponseError[io.circe.Error], NasaData]]]] =    (0 until pageNumb).toList.map(pageIndex => {      val pageUrl = s"http://www.neowsapp.com/rest/v1/neo/browse?page=$pageIndex&size=$pageSize&api_key=${NASA_API_KEY}"      basicRequest.get(uri"$pageUrl")        .response(asJson[NasaData])        .send()    })
 // Note: Future[List] --> List[Future]  val futureOfList: Future[List[Response[Either[ResponseError[io.circe.Error], NasaData]]]] = Future.sequence(listOfFutureResult)
 // Note: 把Response[Either[ResponseError[io.circe.Error], NasaData]] 轉(zhuǎn)為了 Either[Throwable, NasaData]  val respOfEither2Either: Response[Either[ResponseError[io.circe.Error], NasaData]] => Either[Throwable, NasaData] = resp => {    println(s"resp==>  code:${resp.code.code}  ${resp.statusText}")    val newEither: Either[Throwable, NasaData] = resp.body match {      case Left(respErr) => Left(respErr.getCause)      case Right(nasaData) => Right(nasaData)    }    newEither  }
 val futureOfListOfEither: Future[List[Either[Throwable, NasaData]]] = futureOfList.map(listOfResp => {    listOfResp.map(respOfEither2Either)  })
 val listOfEither2TupleOfList: List[Either[Throwable, NasaData]] => (List[Throwable], List[NasaData]) = listE => {    listE.foldLeft(List[Throwable](), List[NasaData]())((acc, eData) => {      eData match {        case Right(nasaData) => (acc._1, acc._2 :+ nasaData)        case Left(t) => (acc._1 :+ t, acc._2)      }    })  }
 val futureOfTupleOfList = futureOfListOfEither map listOfEither2TupleOfList
 val result = Await.result(futureOfTupleOfList, 1.minute)  println(s"Exceptions in Response: $result._1")  println(s"Data in Response: $result._2")  

另,Akka HTTP默認(rèn)主機(jī)連接數(shù)是32個(gè),所以需要修改applicaiton.confg配置以支持更多連接數(shù)。

akka.http.host-connection-pool.max-open-requests = 128

“STTP的基本使用方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI