Martin GOYOT Martin GOYOT - 10 months ago 61
Java Question

Action composition and async in Play Framework 2.5 in Java

I want to create an action that I can use with the

annotation style. This action will need to proceed to an RPC call so if I understood correctly the documentation I should rather put this in an async way.

This is what I tried to do until now:

public class GetUserIdAction extends play.mvc.Action.Simple {

public CompletionStage<Result> call(Http.Context context) {
String token = "";

if (StringUtils.isEmpty(token)) {

CompletionStage<Http.Context> promiseOfUpdatedContext = CompletableFuture.supplyAsync(() -> setUserIdForToken(context, token));

return promiseOfUpdatedContext.thenApply(ctx ->;

private Http.Context setUserIdForToken(Http.Context context, String token) {
context.args.put("user_id", authenticationManager.getUserIdForToken(token));
// The AuthenticationManager is issuing an RPC call and thus may take some time to complete.
return context;

Set aside the fact that
is always empty and
is not set, this is just a quick meaningless example, my IDE is complaining on the
part. For what I understand, it is expecting a
and gets something more like a

What is a way to deal with it? Cause here all I want is to put some information in the Context and then continue the

Or maybe I'm trying to do something stupid and composed actions are already asynchronous?


You have a CompletionStage<Something> and want to end with a CompletionStage<Result>. The easiest way to achieve that is using thenCompose.

Here is an example, with a small change: I have a CompletableFuture to get the token and only then I add it to the HttpContext

public CompletionStage<Result> call(final Http.Context context) {
    final String token = "";

    if (StringUtils.isEmpty(token)) {

    return CompletableFuture.supplyAsync(() -> {
        // do something to fetch that token
        return "your_new_token";
    }).thenCompose(tokenReceived -> {
        context.args.put("user_id", tokenReceived);