Search code examples
lambdaplayframework-2.0java.util.concurrentconcurrent.futurescompletable-future

Using CompletionStage to return results


I am new to play framework and Java8. I am trying to write a simple web service in Play which conforms to the Asynch model and allows the web service call to return quickly, leaving heavy lifting for async thread.

I have a very basic operation

public CompletionStage<Result> getPeople() {

}

The real processing in the call has to load the persons data from database. The db method is

List<People> people = dbService.getPeople();
return ok(Json.tojson(people));

The dbMethod is itself async and returns CompletionStage>.

CompletionStage<List<People>> getPeople() {}

So my problem is that I fail to understand how best to program web service to that the method does not block.

I can do something like this in my handler

public CompletionStage<Result> getPeople() {
  CompletableFuture.completedFuture(
    ok(Json.toJson(dbservice.getPeople().get())));
}

Problem with this is that the controllel blocks at "get" method and also that it throws exception which I don't know how to handle other than using standard try-catch block (which also makes it non-async).

I have also tried something like this

return CompletableFuture.supplyAsync(() -> {
    return dbService.getPeople();
    }).thenApply(i -> { ok(Json.toJson(i.get())); } );

But that gives compile errors.

I will really appreciate some help here; as I am very new to Java async programming and despite reading lots of tutorials I am unclear how to best use these.

Thank you all.


Solution

  • You should return your future but transform the result to a play.mvc.result:

    public CompletionStage<Result> getPeople() {
        return dbService.getPeople().thenApply(peopleList -> 
            ok(Json.toJson(peopleList))
        );
    }