Vert.x is a highly performant asynchronous library. It is a great fit for IO heavy applications. Good thing about vert.x is, it is just a library that you can create the objects anywhere and use it out of the box. You can easily embed this to your application. Vert.x 4 has added Future support. This Future io.vertx.core.Future is not same as java.util.concurrent.Future You can refer the javadoc here.

You need to include the maven dependency. Or you can clone this repository

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-web-client</artifactId>
  <version>4.4.2</version>
</dependency>

Every asynchronous operation method from Vert.x has an alternate version of it to return a Future. Prior to Vert.x 4 every asynchronous operation needs to be passed a callback which leads to callback hell. Lets look at a http client usage.

Vert.x 3 callback

client.getAbs(url).send(response -> {
  System.out.println("Response: "+ response);
});

Vert.x 4 Future

Future<HttpResponse<Buffer>> future = client.getAbs(url).send();
future.onComplete(response -> {
  System.out.println("Response: " + response);
});

They both seem to be similar at first. The Future version still has callback for onComplete. This is very useful when we pass around the future to different part of the code and continue the completion there. This usage avoids callback hell or nesting callbacks on multiple levels.

compose

Let's take an example with a shortened link. On hitting the shortened link gives the original link. This means we need to perform two asynchronous operations and the second operation is dependant on the first operation. This can be written in Vert.x 4 without nesting callbacks.

Future<HttpResponse<Buffer>> future = client.getAbs(shortLink).send();
future.compose(resp -> {
    String originalLink = resp.bodyAsString();
    return client.getAbs(originalLink).send();
});

The compose method from Future returns another Future. it is useful to chain multiple dependant operations as if they were written line by line in a blocking java code. This Future object now can be returned to anywhere in the code to execute different operation with the result of it.

map

You can use map method to transform the result of the future. The mapping operation is done asynchronously when the result is available.

public Future<JsonObject> fetchJsonData(WebClient client, String url) {
  Future<HttpResponse<Buffer>> future = client.getAbs(url).send();
  return future.map(res -> res.bodyAsJsonObject());
}