WS in Play become incredible complex for 2.6.X
Asked Answered
E

3

5

For Play 2.3.X the WS module is very easy to be used:

WS.url(s"http://$webEndpoint/hand/$handnumber").get()

For the such simple and strightforward usage.

While in Play 2.6.x according to the link : https://www.playframework.com/documentation/2.6.x/JavaWS You need to create a http client firstly.

WSClient customWSClient = play.libs.ws.ahc.AhcWSClient.create(
    play.libs.ws.ahc.AhcWSClientConfigFactory.forConfig(
            configuration.underlying(),
            environment.classLoader()),
            null, // no HTTP caching
            materializer);

And what's more, you also need a materializer and an akka system to support the materializer.

String name = "wsclient";
ActorSystem system = ActorSystem.create(name);
ActorMaterializerSettings settings =       ActorMaterializerSettings.create(system);
ActorMaterializer materializer = ActorMaterializer.create(settings, system, name);
// Set up AsyncHttpClient directly from config
AsyncHttpClientConfig asyncHttpClientConfig = new  DefaultAsyncHttpClientConfig.Builder()
    .setMaxRequestRetry(0)
    .setShutdownQuietPeriod(0)
    .setShutdownTimeout(0).build();
AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(asyncHttpClientConfig);

// Set up WSClient instance directly from asynchttpclient.
WSClient client = new AhcWSClient(
asyncHttpClient,
materializer

);

I knew it will add more features to the WS client, but when I just want a simple http client, the usage become unaccept complex, it's so wired.

Euglena answered 11/10, 2017 at 8:10 Comment(1)
After deeper research in internet, I found that, after Play2.6 the WS library using Akka Streaming feature instead of Non-blocking IO. For more information, see my blog wherby.github.io/ask-question .Euglena
D
5

The page you link to says:

We recommend that you get your WSClient instances using dependency injection as described above. WSClient instances created through dependency injection are simpler to use because they are automatically created when the application starts and cleaned up when the application stops.

It shouldn't then surprise you that manually creating instance of WSClient is tedious.

And the same page describes how to use an injected version of WSClient:

import javax.inject.Inject;

import play.mvc.*;
import play.libs.ws.*;
import java.util.concurrent.CompletionStage;

public class MyClient implements WSBodyReadables, WSBodyWritables {
    private final WSClient ws;

    @Inject
    public MyClient(WSClient ws) {
        this.ws = ws;
    }
    // ...
}

This is as simple as it's used to be in the previous versions. Actually, in previous Play versions you also could have created the custom instance of WSClient, and that used to have comparable complexity (modulo Akka stuff).

Disciplinarian answered 11/10, 2017 at 8:23 Comment(3)
Yes, the interface of WS is keep consistence with perivious one, which is simple. But in the later version, you need creat a WSClient yourself, and creating of WSClient which will be tedious. For Play 2.3.x, you don't need to worry about how to creat the client, but just use like in my post. In later version, you need to implement a client and inject to the app. Just as your post, you need to "creat the custom instance of WSClient". Is there better way to have default WSClient which user don't need to worry about how to implement it.Euglena
No, you don't need to create a custom instance of WSClient if you use dependency injection. It will be created by Play framework for you. It's pretty much the same as it used to be in Play 2.3, with the difference you don't use static factory, but rather dependency injection.Disciplinarian
Maybe I don't describe clearly. My project is not a play project. So I don't have the injection. But if use the play framwork, you are right. If you use scala 2.12, you use the WS lib without Play framwork, then you will need creat the client instance yourself.Euglena
E
1

Finally I use ScalaJ-http, https://github.com/scalaj/scalaj-http

Which is very easy to use:

import scalaj.http._
...
response= Http("http://localhost:5000/health").asString

Which is simple as WS in play 2.3.6

For Play 2.6.x the framework may not create the default ws for you and see the example of https://github.com/playframework/play-scala-tls-example/blob/2.6.x/app/Main.scala

Euglena answered 11/10, 2017 at 13:24 Comment(2)
Keep in mind this is a blocking API. As explained by @Haspemulator, you can easily inject an instance of WSClient and use it without any additional complexity. Any reason to not doing so?Vardon
The guy told in the last comment that his project is not a Play project :) So the original question dose not make a lot of sense anymore ))Snick
S
0

For people using Scala Play with fully DI support one solution to create WSClient instance is Play.current.injector.instanceOf[WSClient]. That also useful when updating to Scala Play 2.6 with small changes without adding DI support to all.

Subdivide answered 20/9, 2018 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.