WS in Play become incredible complex for 2.6.X

1.6k Views Asked by At

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.

3

There are 3 best solutions below

3
On BEST ANSWER

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).

0
On

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.

2
On

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