Some APIs offers paginated data.
I want to call the API and retrieve the data of all pages.
I was thinking an implementation of it using recursion.
I will call it to retrieve the first page data and the url of next page. If next page is empty it means there's no more data to retrieve.
I have this code, which is not really calling an API but it is useful to implement the recursive function I need. The issue I'm facing is that I can't add the tailrec annotation, I can't transform it to be tail recursive.
How can I achieve it?
Code for simulating the API which return results in pages:
final case class Response(data: List[Int], nextUrl: Option[String])
object Api {
def getNumbers(url: String): Future[Response] = {
url match {
case "1" => Future.successful(Response(List(1, 2), Option("2")))
case "2" => Future.successful(Response(List(3, 4), Option("3")))
case "3" => Future.successful(Response(List(5, 6), None))
case _ => Future.failed(new RuntimeException("Error!"))
}
}
}
Function/method to call the API, which I want to convert it to tail recursion:
def getPaginatedData(url: String): Future[Seq[Int]] = {
// @tailrec
def loop(url: String, acc: Seq[Int]): Future[Seq[Int]] = {
Api.getNumbers(url).flatMap { response =>
response.nextUrl match {
case None => Future.successful(acc ++ response.data)
case Some(link) => loop(link, acc ++ response.data)
}
}
}
loop(url, List.empty)
}
To run the example:
def main(args: Array[String]): Unit = {
SomeService.getPaginatedData("1").onComplete {
case Failure(e) => println(s"Error! $e")
case Success(value) => println(value)
}
}