scalaplayframeworkws-clientscala-2.12

WS in Play become incredible complex for 2.6.X


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.


Solution

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