0

Hello I'm writing scala code to pull the data from API. Data is paginated, so I'm pulling a data sequentially. Now, I'm looking a solution to pulling multiple page parallel and stuck to create WSClient programatically instead of Inject.

Anyone have a solution to create WSClient ?

I found a AhcWSClient(), but it required to implicitly import actor system.

user670097
  • 159
  • 1
  • 3
  • 11
  • If you do not already have an actor system running, you must create one. You can find an example in the README of WSClient's github repo: https://github.com/playframework/play-ws#scala-1 – Aki Dec 06 '18 at 23:14
  • You're using WSClient standalone (without a playframework application), aren't you? – Aki Dec 06 '18 at 23:15
  • From your question it is not clear why you need to create an explicitly new instance of a `WSClient`. How is this related to pagination? I believe `WSClient` supports sending several requests in parallel using one instance of `WSClient`. – SergGr Dec 06 '18 at 23:40

2 Answers2

3

When you cannot Inject one as suggested in the other answer, you can create a Standalone WS client using:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import play.api.libs.ws._
import play.api.libs.ws.ahc.StandaloneAhcWSClient

implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
val ws = StandaloneAhcWSClient()
Jethro
  • 3,029
  • 3
  • 27
  • 56
  • thanks. I am using compile time injection and so I suppose I can't use @Inject. Is there a way to instantiate `WS`. Is there a way to instantiate `ws` ? – Manu Chadha Dec 21 '20 at 13:01
  • I think I found out that I can also use AhcWSClient. What is the difference between `AhsWSClient` and `StandaloneAhcWSClient` one? - https://www.playframework.com/documentation/2.6.x/api/scala/play/api/libs/ws/ahc/AhcWSClient.html – Manu Chadha Dec 21 '20 at 13:06
2

No need to reinvent the wheel here. And I'm not sure why you say you can't inject a WSClient. If you can inject a WSClient, then you could do something like this to run the requests in parallel:

class MyClient @Inject() (wsClient: WSClient)(implicit ec: ExecutionContext) {

  def getSomething(urls: Vector[String]): Future[Something] = {
    val futures = urls.par.map { url =>
      wsClient.url(url).get()
    }
    Future.sequence(futures).map { responses =>
      //process responses here. You might want to fold them together
    }
  }

}
Lasf
  • 2,536
  • 1
  • 16
  • 35