Skip to main content

Vert.x 3.4.0.Beta1 release


we have released 3.4.0.Beta1, this release is the biggest since Vert.x 3.0.0 with plenty of great features.

You can use consume it in your projects from Maven or Gradle as usual with the version 3.4.0.Beta1 or read

Let me outline the important changes you can already find in this Beta1.

Vert.x Web Client

In a simple sentence “Vert.x Web Client is to Vert.x HttpClient what Vert.x Web is to HttpServer”

The Web Client makes it easy to do HTTP request/response interactions with a web server, and provides advanced features like:

  • Json body encoding / decoding
  • request/response pumping
  • request parameters
  • unified error handling
  • form submissions
  • and more!

Built on top of HttpClient, it naturally inherits its features and provides a better API, let me give an overview in one example:

WebClient client = WebClient.
  .get(8080, "", "/some-uri")
  .send(ar -> {
    if (ar.succeeded()) {

      HttpResponse<User> response = ar.result();
      User user = response.body();

      System.out.println("Received response with status code" + response.statusCode() + " with body " +
        user.getFirstName() + " " + user.getLastName());
    } else {
      System.out.println("Something went wrong " + ar.cause().getMessage());

RxJava singles

RxJava is a very popular Java extension and in this release we focused on the API usability with the support of the Single RxJava type.

The new methods are prefixed by rx and deprecates the Observable suffixed methods.

So instead of starting a server with listenObservable now you use rxListen:

HttpServer server = vertx.createHttpServer();
Single<HttpServer> single = server.rxListen(8080, "localhost");
  ok -> System.out.println("Server started"),
  err -> System.out.println("Something went wrong " + err.getMessage()));

One noticeable difference with the previous API, is that the listen method is called when the Single is subscribed.

This is very handy when combined with the new web client:

Single<HttpResponse<Buffer>> single = client
   .get(8080, "", "/some-uri")

// Send the request
single.subscribe(response -> System.out.println("got response " + response.statusCode());

// Send the request again
single.subscribe(response -> System.out.println("got response " + response.statusCode());


In this beta you can try Vert.x for Kotlin.

Vert.x for Kotlin is based on the Java API and provides also the execution of Kotlin Verticles.

import io.vertx.core.*
import io.vertx.kotlin.core.http.HttpServerOptions

class Server : AbstractVerticle() {

  override fun start() {

        // We provide Kotlin extension methods, allowing to use an idiomatic Kotlin API for building these options
            port = 8080,
            host = "localhost"
        .requestHandler() { req ->
          req.response().end("Hello from Kotlin")
    println("Server started on 8080")

It can be directly ran from the command line:

julien:vertx-kotlin-example julien$ vertx run Server.kt
Server started on 8080
Succeeded in deploying verticle

As you can see, Kotlin is using the Java API directly, and we thought that it might be a cool thing to do the same with Groovy support. So we have reconsidered our Groovy support and now it uses the plain Java API, without losing the existing features.

Thanks to Groovy extension methods, idiomatic Groovy is still supported while benefiting from the full Java API!

Scala support is also planned for 3.4.0 and will be released soon, watch @vertx_project.

The microservices story goes on…

Our APIs have matured and now they have been moved out of tech preview, of course this wasn’t enough and we now have Vert.x Config, an extensible way to configure Vert.x applications supporting File, json, ENV, system properties, HTTP, Kubernetes Configmap, Consul, Spring Config Server, Redis, Git, Zookeeper, … stores as well as several formats: properties file, YAML and Hocon.

Here is a small example:

ConfigStoreOptions httpStore = new ConfigStoreOptions()
  .setConfig(new JsonObject()
    .put("host", "localhost").put("port", 8080).put("path", "/conf"));

ConfigStoreOptions fileStore = new ConfigStoreOptions()
  .setConfig(new JsonObject().put("path", "my-config.json"));

ConfigStoreOptions sysPropsStore = new ConfigStoreOptions().setType("sys");

ConfigRetrieverOptions options = new ConfigRetrieverOptions()

ConfigRetriever retriever = ConfigRetriever.create(vertx, options);

Vert.x Config also supports push based notification style:

ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
  .endHandler(v -> {
    // retriever closed
  .exceptionHandler(t -> {
    // an error has been caught while retrieving the configuration
  .handler(conf -> {
    // the configuration

Vertx MQTT Server

Vert.x MQTT Server is able to handle connections, communication and messages exchange with remote MQTT clients. Its API provides a bunch of events related to protocol messages received by clients and exposes allow to send messages to them.

Here is a small effective example of creating, the Vert.x way!

MqttServerOptions options = new MqttServerOptions()

MqttServer server = MqttServer.create(vertx, options);

server.endpointHandler(endpoint -> {

  System.out.println("connected client " + endpoint.clientIdentifier());

  endpoint.publishHandler(message -> {

    System.out.println("Just received message on [" + message.topicName() + "] payload [" +
      message.payload() + "] with QoS [" +
      message.qosLevel() + "]");


server.listen(ar -> {
  if (ar.succeeded()) {
    System.out.println("MQTT server started and listening on port " + server.actualPort());
  } else {
    System.err.println("MQTT server error on start" + ar.cause().getMessage());

Vert.x SQL streaming

We now support streaming style for SQL queries:

connection.queryStream("select * from test", stream -> {
  if (stream.succeeded()) {
    SQLRowStream sqlRowStream = stream.result();

      .handler(row -> {
        // do something with the row...
      .endHandler(v -> {
        // no more data available, close the connection
        connection.close(done -> {
          if (done.failed()) {
            throw new RuntimeException(done.cause());

And with the RxJava API:

  .rxGetConnection() // Connect to the database
  .flatMapObservable(conn -> { // With the connection...
    return conn.rxUpdate("CREATE TABLE test(col VARCHAR(20))") // ...create test table
      .flatMap(result -> conn.rxUpdate("INSERT INTO test (col) VALUES ('val1')")) // ...insert a row
      .flatMap(result -> conn.rxUpdate("INSERT INTO test (col) VALUES ('val2')")) // ...another one
      .flatMap(result -> conn.rxQueryStream("SELECT * FROM test")) // ...get values stream
      .flatMapObservable(sqlRowStream -> {
        return sqlRowStream.toObservable() // Transform the stream into an Observable...
          .doOnTerminate(conn::close); // ...and close the connection when the stream is fully read or an error occurs
  }).subscribe(row -> System.out.println("Row : " + row.encode()));


In addition to all these brillant features here is a list of more-than-noticeable things you have in this Beta1:

  • Vert.x Infinispan replaces Vert.x Jgroups cluster manager
  • Vert.x Consul Client provides a full fledged client for Consul
  • Oauth2 predefined configuration with 16 settings from Azure Active Directory, to Twitter with the usual suspects (Facebook, LinkedIn, …)
  • Http client now follow redirects

You can use and consume it in your projects from Maven or Gradle as usual with the version 3.4.0.Beta1 or read

Last but not least, I want to personally thank all the people that contributed to this release, beyond the Vert.x core team, the actual Vert.x committers and many other people who have given a lot of effort to this upcoming 3.4.0!!!!