Reputation: 926
I'm pretty new to Scala, and what I'm trying to achieve is to make enough calls to an API with different offset until I get all the results.
Here's a simplified version of what I have, and I was wondering if there is a more idiomatic Scala way to do it. (The code sample might not be 100% accurate, it's just something I put up as an example)
def getProducts(
limit: Int = 50,
offset: Int = 0,
otherProducts: Seq[Product] = Seq()): Future[Seq[Product]] = {
val eventualResponse: Future[ApiResponse] = apiService.getProducts(limit, offset)
val results: Future[Seq[Product]] = eventualResponse.flatMap { response =>
if (response.isComplete) {
logger.info("Got every product!")
Future.successful(response.products ++ otherProducts)
} else {
logger.info("Need to fetch more data...")
val newOffset = offset + limit
getProducts(limit, newOffset, otherProducts ++ response.products)
}
}
results
}
Passing the otherProducts
parameter just doesn't feel right :P
Thanks in advance for any suggestions :)
Upvotes: 4
Views: 290
Reputation: 5039
It seems you've exposed the tail recursion implementation, which is a bit like implementation detail in functional programming.
As for me, I typically wrap such functions into an external call without accumulator parameter (otherProducts
):
def getProducts(limit: Int = 50, offset: Int = 0): Future[Seq[Product]] = {
def loop(limit: Int = 50,
offset: Int = 0,
acc: Seq[Product] = Seq()): Future[Seq[Product]] = ... your code with tail recursion...
loop(limit, offset)
}
But it is just a matter of taste, and of course it is valid if otherProducts
is just a fancy name for tailrec accumulator.
Upvotes: 5