Use WSClient in scala app (play framework) - scala

I'm not sure if there's something really basic that I'm missing, but I can't figure out how to use WSClient. I've seen all of the examples saying you need to pass the WSClient to a class as a dependency, which I've done, but when I run the program what do I actually pass to my class?
For example, my class signature is:
class myClassName(ws: WSClient)
But when I instantiate the class what do I actually pass to it? I'm also happy to ignore the Play! framework stuff if that makes it easier and just use SBT to run it (which I'm more familiar with).

It's unclear where you might be using a WSClient, but it is recommended that you let the Play framework 'manage' the instance of the client. When you instantiate your application, it gets injected:
class Application #Inject() (ws: WSClient) extends Controller {
...
}
What that means is that inside the ... you have access to ws as a value. You can instantiate myClassName using it:
class Application #Inject() (ws: WSClient) extends Controller {
val myclass = myClassName(ws) // passes the injected WSClient to myClassName
}
Or you can write a function that returns the WSClient, so some other area of your code can call into your Application object to get a object handler for it.
But the key is that the Application object gets that handle because of injection, which is the #Inject annotation.
If you need to generate a WSClient and manage it manually, there are good instructions here. The recommended implementation is reliant on Play! framework libraries, but doesn't depend on the Application.

Related

How to use guice dependency injection in Play tests (Play 2.6.3)

I have a test specification called MyTestSpec. The aim it is to test a controller that uses dependency injection in its constructor.
class StatusController #Inject()(cc: ControllerComponents, counter: Counter) extends AbstractController(cc) { ...
The Counter class is another controller that provides a status over to the other. When I now try to test this controller, I have the option to either mock the required Counter class, construct the whole chain of controllers / dependencies or inject it. Let's ignore mocking for now, although it probably would be the more correct thing to do.
The issue is that always when I try to inject the Counter controller, I get a NullPointerException.
What I tried so far:
Inject the Counter into the constructor of MyTestSpec, but then MyTestSpec won't even be constructed and tested.
Inject into a local var with the #Inject annotation.
Inject into a val via app.injector.instanceOf[Counter].
Inject via the shortform inject[Counter].
All don't actually give me this other Controller.
Below a rough outline of the test, the new application to get started with Play can be easily adjusted to demonstrate the issue:
class MyTestSpec extends PlaySpec with GuiceOneAppPerTest with Injecting {
"StatusController GET" should {
"render the status page from a new instance of controller" in {
val controller = new StatusController(stubControllerComponents(), counter)
...
}
}
The question: is there a way to simply inject this Counter controller? If there is no simple way, the follow on question would be what components I can then inject anyway if I am already being restrained... ?
Note: this is different to the question asked here, although I tried the solution provided in it.
Note 2: thank you to the Play and ScalaTest developers as well as all these contributors behind the scenes - a wonderful framework.

How do I create thread pools in Play 2.5.x?

I am currently on Play 2.4.2 and have successfully created thread pools using the following below:
package threads
import scala.concurrent.ExecutionContext
import play.api.libs.concurrent.Akka
import play.api.Play.current
object Contexts {
implicit val db: ExecutionContext = Akka.system.dispatchers.lookup("contexts.db-context")
implicit val pdf: ExecutionContext = Akka.system.dispatchers.lookup("contexts.pdf-context")
implicit val email: ExecutionContext = Akka.system.dispatchers.lookup("contexts.email-context")
}
and then in the code with...
Future{....}(threads.Contexts.db)
We are ready to upgrade to Play 2.5 and having trouble understanding the documentation. The documentation for 2.4.2 uses Akka.system.dispatchers.lookup, which we use without issue. The documentation for 2.5.x uses app.actorSystem.dispatchers.lookup. As far as I know, I have to inject the app into a Class, not an Object. Yet the documentation clearly uses an Object for the example!
Has anyone successfully created thread pools in Play 2.5.x that can help out? Is it as simple as changing Contexts to a class, then injecting it wherever I would like to use this threading? Seems odd since to use the default ExecutionContext I just have to make an implicit import.
Also, we are using Play scala.
If you simply change your Contexts to a class, then you will have to deal with how to get an instance of that class.
In my opinion, if you have a number of thread pools that you want to make use of, named bindings are the way to go. In the below example, I will show you how you could accomplish this with guice.
Note that guice injects depedencies at runtime, but it is also possible to inject dependencies at compile time.
I'm going to show it with the db context as an example. First, this is how you will be using it:
class MyService #Inject() (#Named("db") dbCtx: ExecutionContext) {
// make db access here
}
And here's how you could define the binding:
bind[ExecutionContext].qualifiedWith("db").toProvider[DbExecutionContextProvider]
And somewhere define the provider:
class DbExecutionContextProvider #Inject() (actorSystem: ActorSystem) extends Provider[ExecutionContext] {
override def get(): ExecutionContext = actorSystem.dispatchers.lookup("contexts.db-context")
}
You will have to do this for each of your contexts. I understand this may be a little cumbersome and there may actually be more elegant ways to define the bindings in guice.
Note that I have not tried this out. One issue you might stumble upon could be that you'll end up with conflicts, because play already defines a binding for the ExecutionContext in their BuiltinModule. You may need to override the binding to work around that.

How to get application.conf variable in an object using Scala and Play 2.5.x?

I used to get the application.conf variable in Play 2.4.x with Play.current.configuration.getString('NAME_HERE'), and it was working good in class, object and companion object too.
Now, I'm using Play 2.5.4 with Scala in a new project, and I won't use this Play.current, because it's deprecated, but there is an alternative using DI, like this :
class HomeController #Inject() (configuration: play.api.Configuration) extends Controller {
def config = Action {
Ok(configuration.underlying.getString("db.driver"))
}
}
This DI Injection works like a charm in class, but in this project, I need to get the variable db.driver in a object? And as far I know, with an object I can't use DI.
Maybe using Guice would help?
You can use #Singleton annotated class instead of object
trait Foo {}
#Singleton
class FooImpl #Inject()(configuration: play.api.Configuration)) extends Foo {
//do whatever you want
}
#Singleton makes the class singleton.It feels bit awkward because Scala itself natively have syntax object to create a singleton, But this is the easiest and probably best solution to DI into a singleton.
You also may create the singleton eagerly like the code below.
bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()
for more detail Info, You can look up Google Guice Wiki and Playframework site
EDIT
How you call it is exactly the same as how you DI in Playframework2.5.
class BarController #Inject()(foo: Foo) extends Controller {
//Do whatever you want with Foo
}
Guice basically generates new instance every time you DI, Once you put #Singleton, Guice use only one instance instead.
DI is for anti-high coupling.So when you want to use a class you defined from another class,You need to DI otherwise the classes are highly coupled which end up making it harder to code your unit test.
FYI, You can use them outside of Play with this technique.
Create an Instance of class which does DI via Playframework Guice Independently in Scala
Have you tried
import com.typesafe.config.ConfigFactory
val myConfig = ConfigFactory.load().getString("myConfig.key")
Above approach doesn't require you to convert your object to singleton class.
You can do
Play.current.configuration
however that will (probably) no longer be possible with Play 2.6.
Ideally, however, you would pass the configuration in as a parameter to that method of the object or, use a class instead of an object.
What I somtimes do to migrate 'from object to class':
class MyComponent #Inject() (config: Configuration) {
// here goes everything nice
def doStuff = ???
}
object MyComponent {
#deprecated("Inject MyComponent")
def doStuff = {
val instance = Play.current.injector.instanceOf[MyComponent]
instance.doStuff
}
}
This way, you're not breaking existing code while all users of your methods can slowly migrate to using classes.

Play 2.5 + Slick + DI Issue

I have DAO defined as follows:
#Singleton
class MyDAO #Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
I have an integration test which references this DAO:
class SomeIntegrationTest {
lazy val someVal = new MyDAO
}
How can I inject the DatabaseConfigProvider into the MyDAO in the SomeIntegrationTest? I cannot inject one in the constructor of the test because test classes do not take constructor parameters.
You can get your dependency injected by doing
val dbConfigProvider = app.injector.instanceOf[DatabaseConfigProvider]
where app is an instance of your FakeApplication. Without it, there is no way Play can inject your dependency for you. You can get an instance of FakeApplication by extending OneAppPerSuite, see the provided link for more details.
In general, there are three main ways you can gain access to some object(s) in your test:
manual creation of objects using the new keyword (not considered best practice)
injection via injector as shown here (either injecting objects directly or injecting a provider/factory which can get them for you)
in case of unit testing a class with some dependencies, having those dependencies mocked

How do I give global access to an object in Scala without making it a singleton or passing it to everything?

I have a Logger class that logs events in my application. While I only need one instance of the logger in this application, I want this class to be reusable, so I don't want to make it a singleton and couple it with my specific needs for this application.
I want to be able to access this Logger instance from anywhere in the application without having to create a new one every time or pass it around to every class that might need to log something. What I currently do is have an ApplicationUtils singleton that I use as the point of access for the application's Logger:
object ApplicationUtils {
lazy val log : Logger = new Logger()
}
Then I have a Loggable trait that I add to classes that need the Logger:
trait Loggable {
protected[this] lazy val log = ApplicationUtils.log
}
Is this a valid approach for what I am trying to accomplish? It feels a little hack-y. Is there a better approach I could be using? I'm pretty new to Scala.
Be careful when putting functionality in objects. That functionality is easily testable, but if you need to test clients of that code to make sure they interact with it correctly (via mocks and spies), you're stuck 'cause objects compile to final classes and thus cannot be mocked.
Instead, use this pattern:
trait T { /* code goes here */ }
object T extends T /* pass this to client code from main sources */
Now you can create Mockito mocks / spies for trait T in your test code, pass that in and confirm that the interactions of the code under test with the trait T code are what they should be.
If you have code that's a client of T and whose interactions with it don't require testing, you can directly reference object T.
To address what you're trying to do (rather than what you're asking), take a look at TypeSafe's scalalogging package. It provides a Logging trait that you can use like so:
class MyClass extends Logging {
logger.debug("This is very convenient ;-)")
}
It's a macro-based wrapper for SLF4J, so something like logger.debug(...) gets compiled as if (logger.isDebugEnabled) logger.debug(...).