首页 > 解决方案 > Scala递归api调用

问题描述

val identifiers = List("id1","id2","id3","id4","id5","id5","id7","id8","id9","id10")

列表中有 10 个 id,我需要使用一些 API 调用来获取所有 id 信息,它可以是 post 或 get 方法。

但这里的挑战是如果 id 超过 3,返回 id 信息的 API 将不会返回结果。

所以我想以批处理格式对所有这些 ID 进行 API 调用。批量大小最大值为 3。因为如果 id 大于 3,API 将不会返回结果。

有什么方法可以实现批量 3 的 API 调用?

curl 中的示例 API

curl --location --request POST 'https://test/search' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "filters": {
           "identifier": ["id1", "id2", "id3"]
        }
    }
}'


标签: scalaapiscala-collections

解决方案


您可以使用grouped2 或 3 个(无论您需要什么)元素进行分组。

以下代码显示了如何分组、调用返回 Future 的方法并以 List 的形式接收所有响应。

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.concurrent.duration._

//Emulate a call that returns a Future
def apiCall(ids: List[String]): Future[String] = Future(ids.mkString("[", ",", "]"))

val ids       = List("ID1", "ID2", "ID3", "ID4", "ID5")
val subIds    = ids.grouped(2).toList
//val responses = Future.sequence(subIds.map(apiCall))
val responses = Future.traverse(subIds)(apiCall)
val all       = Await.result(responses, 2.seconds)
println(all)

这打印

List([ID1,ID2], [ID3,ID4], [ID5])

您可以使用各种库进行 http 请求,但最简单的(在我看来)是scalaj-http

方法 apiCall 可以实现如下

def apiCall(ids: List[String]) = Future {
  import scalaj.http.Http
  val idsAsJsonArray = ids.map(id => "\"" + id + "\"").mkString("[", ",", "]")
  Http("https://test/search")
    .postData(s"""
      |{
      |    "request": {
      |        "filters": {
      |           "identifier": $idsAsJsonArray
      |        }
      |    }
      |}
      |""".stripMargin)
    .header("Content-Type", "application/json")
    .asString
    .body
}


推荐阅读