11

On Async Http Client documentation I see how to get a Future<Response> as the result of an asynchronous HTTP Get request simply doing, for example:

AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
Future<Response> f = asyncHttpClient
      .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
      .execute();
Response r = f.get();

However, for convenience I would like to get a CompletableFuture<T> instead, for which I could apply a continuation that converts the result in something else, for instance deserializing the response content from Json into a Java object (e.g. SoccerSeason.java). This is what I would like to do:

AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
CompletableFuture<Response> f = asyncHttpClient
     .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
     .execute();
f
     .thenApply(r -> gson.fromJson(r.getResponseBody(), SoccerSeason.class))
     .thenAccept(System.out::println);

According to Async Http Client documentation the only way to do this is through an AsyncCompletionHandler<T> object and using a promise. So I built an auxiliary method to that end:

CompletableFuture<Response> getDataAsync(String path){
    CompletableFuture<Response> promise = new CompletableFuture<>();
    asyncHttpClient
            .prepareGet(path)
            .execute(new AsyncCompletionHandler<Response>() {
                @Override
                public Response onCompleted(Response response) throws Exception {
                    promise.complete(response);
                    return response;
                }
                @Override
                public void onThrowable(Throwable t) {
                    promise.completeExceptionally(t);
                }
            });
    return promise;
}

With this utility method I can rewrite the previous example just doing:

getDataAsync("http://api.football-data.org/v1/soccerseasons/398")
    .thenApply(r -> gson.fromJson(r.getResponseBody(), SoccerSeason.class))
    .thenAccept(System.out::println);

Is there any better way of getting a CompletableFuture<T> from an Async Http Client request?

Miguel Gamboa
  • 8,855
  • 7
  • 47
  • 94

1 Answers1

15

With AHC2:

CompletableFuture<Response> f = asyncHttpClient
     .prepareGet("http://api.football-data.org/v1/soccerseasons/398")
     .execute()
     .toCompletableFuture();
Stephane Landelle
  • 6,990
  • 2
  • 23
  • 29
  • Could you include a `CompletableFuture` usage example in `Readme.md` of [AHC2 repo](https://github.com/AsyncHttpClient/async-http-client)? I think it's useful. – Miguel Gamboa May 31 '16 at 11:08
  • @StephaneLandelle The documentation says - "Beware that canceling this CompletableFuture won't properly cancel the ongoing request. There's a very good chance we'll return a CompletionStage instead in the next release." Wondering if there's a proper CompletableFuture available in the latest release, which will cancel the requests correctly too? – user1571307 Aug 06 '18 at 11:47