Documentation

The Play WS API

Sometimes you want to call other HTTP services from within a Play application. Play supports this via its play.libs.WS library, which provides a way to make asynchronous HTTP calls.

A call made by play.libs.WS should return a Promise<WS.Response>, which you can handle later with Play’s asynchronous mechanisms.

Imports

To use WS, first import the following packages:

import play.libs.WS;
import play.mvc.Result;

import static play.libs.F.Function;
import static play.libs.F.Promise;

Making HTTP calls

To make an HTTP request, you start with WS.url() to specify the URL. Then you get a builder that you can use to specify HTTP options, such as setting headers. You end by calling a method corresponding to the HTTP method you want to use:

Promise<WS.Response> homePage = WS.url("http://example.com").get();

Alternatively:

Promise<WS.Response> result = WS.url("http://example.com").post("content");

Recovery

If you want to recover from an error in the call transparently, you can use recover to substitute a response:

Promise<WS.Response> callWithRecover = homePage.recover(new Function<Throwable, WS.Response>() {
    @Override
    public WS.Response apply(Throwable throwable) throws Throwable {
        return WS.url("http://backup.example.com").get().get(timeout);
    }
});

Retrieving the HTTP response result

The call is made asynchronously and you need to manipulate it as a Promise<WS.Response> to get the actual content. You can compose several promises and end up with a Promise<Result> that can be handled directly by the Play server:

public static Promise<Result> index() {
    final Promise<Result> resultPromise = WS.url(feedUrl).get().map(
            new Function<WS.Response, Result>() {
                public Result apply(WS.Response response) {
                    return ok("Feed title:" + response.asJson().findPath("title"));
                }
            }
    );
    return resultPromise;
}

Composing results

If you want to make multiple calls in sequence, this can be achieved using flatMap:

public static Promise<Result> index() {
    final Promise<Result> resultPromise = WS.url(feedUrl).get().flatMap(
            new Function<WS.Response, Promise<Result>>() {
                public Promise<Result> apply(WS.Response response) {
                    return WS.url(response.asJson().findPath("commentsUrl").asText()).get().map(
                            new Function<WS.Response, Result>() {
                                public Result apply(WS.Response response) {
                                    return ok("Number of comments: " + response.asJson().findPath("count").asInt());
                                }
                            }
                    );
                }
            }
    );
    return resultPromise;
}

Configuring the HTTP client

The HTTP client can be configured globally in application.conf via a few properties:

# Follow redirects (default true)
ws.followRedirects=true
# Connection timeout in ms (default 120000)
ws.timeout=120000
# Whether to use http.proxy* JVM system properties (default true)
ws.useProxyProperties=true
# A user agent string to set on each request (default none)
ws.useragent="My Play Application"

Next: Integrating with Akka


Found an error in this documentation? The source code for this page can be found here. After reading the documentation guidelines, please feel free to contribute a pull request.