0
votes

I'm looking for a light-bulb moment but haven't had it yet! Using Play Framework 2.5.9 with Java 8 and trying to follow good practice with an asynchronous, non-blocking model.

So my play app exposes a REST service. A GET request to one of the endpoints returns data to the client. In order to retrieve some of that data, my REST service, in turn, needs to call another service.

By making the call to the other service asynchronous and non-blocking, I am unable to include the data in the response from that service in the response to my service.

I guess I want the call from my service to the other service to be synchronous but non-blocking? In that way the thread processing the request in my service is freed up to do something else while I wait for a response from the other service. And I can still include the data from the response in the other service in the response to my service. Is that right?

Here is my current code which is asynchronous (which I don't want) and non-blocking (which I want):

    import play.libs.ws.WSClient;
    import play.libs.ws.WSRequest;
    import play.libs.ws.WSResponse;

    //...........//

    WSRequest request = ws.url(endpointUrl);
    request.get()
            .thenApply(WSResponse::asJson)
            .thenAccept(
                    jsonResult -> {
                        System.out.println(new Date().toString() + " "+ jsonResult.get("blah").get("bluh"));
                    }
            );

I want jsonResult to pull data from jsonResult and return it in the response to my service. Advice appreciated.

1

1 Answers

2
votes

Play process action asynchronously. So feel free to return CompletionStage<Result> from the action.

You need to change thenAccept to thenApply and wrap you result string new Date().toString() ... into a Result:

public CompletionStage<Result> apiData(){
       WSRequest request = ws.url(endpointUrl);
       return request.get()
                .thenApply(WSResponse::asJson)
                .thenApply(
                        jsonResult -> {
                            return ok(new Date().toString() + " "+ jsonResult.get("blah").get("bluh"));
                        }
                );
}