I have a service class, and the service have one method getSomethingFromApi
, now , I want to have play Configuration instance so I can pull stuff from the application.conf, and a play WSClient so I can perform http calls.
this is how I want my service to look:
class MyApiService {
def getSomethingFromApi(whichApi: String): Future[ApiRes] = {
wsClient.url(configuration.getString(whichApi)).withHttpHeaders(("Content-Type", "application/json")).get.map { res =>
response.status match {
case Status.OK => // do something
case _ => throw new Exception
}
}
}
}
and this is the ServicesModule that is wiring my services:
import com.softwaremill.macwire._
trait ServicesModule {
lazy val myService: MyApiService = wire[MyApiService]
}
my question now is what is the right way of using wiring play Configuration and WSClient instances..? cause currently i need those instances in my service but i dont have them, how should i do this the right way?
thanks
With macwire it'll probably look like this
// MyApiService.scala
class MyApiService(wsClient: WSClient) { ... }
// ServicesModule.scala
trait ServicesModule with NingWSComponents {
lazy val wsClient = wire[WSClient]
lazy val apiService = wire[MyApiService]
}
I haven't tried using macwire with play myself, so I have relatively low confidence that it'll work on the first try, but macwire play example suggests mixing in certain Play modules to provide values needed for WSClient. Most likely not all of them are needed, but some might be - soo I'd suggest starting with just NingWSComponents
and gradually adding more until it works.
For the configuration I suggest using something like PureConfig and load the configuration as follows
import pureconfig._
import pureconfig.error.ConfigReaderFailures
case class YourConfClass(name: String, quantity: Int)
val config: Either[pureconfig.error.ConfigReaderFailures,YourConfClass] = loadConfig[YourConfClass]
This then can be passed on to any component of your app using macwire.
As of Play 2.6.X one should use AhcWSComponents
that are provided by the ws
dependency as follows:
In your build.sbt file add the ws dependency to your project
libraryDependencies += ws
In your module trait mix-in the AhcWSComponents
trait and wire the WSClient
trait ServicesModule with AhcWSComponents {
lazy val wsClient = wire[WSClient]
lazy val apiService = wire[MyApiService]
}
In your MyApiServic
e add the WSClient
as a param. to the constructor
class MyApiService(wsClient: WSClient) { ... }
And now you're done. This general rule applies to all provided dependencies.