Getting Started
This guide walks you through adding SmallRye Mutiny Vert.x Bindings to your project and writing a first reactive application.
Prerequisites
- Java 17 or later
- Maven 3.9 or later
Adding the BOM
The simplest way to manage dependency versions is to import the BOM (Bill of Materials) in your pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>vertx-mutiny-clients-bom</artifactId>
<version>${mutiny-vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Replace ${mutiny-vertx.version} with the version you want to use, or define it as a Maven property.
Adding module dependencies
With the BOM imported you can add individual modules without specifying a version. At a minimum you need the core module:
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-core</artifactId>
</dependency>
If you also want to use the reactive HTTP client (WebClient), add:
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-web-client</artifactId>
</dependency>
A complete example
The following program starts an HTTP server that replies with a greeting and then uses WebClient to call it:
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.core.http.HttpServer;
import io.vertx.mutiny.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.mutiny.ext.web.client.HttpResponse;
import io.vertx.mutiny.ext.web.codec.BodyCodec;
public class GettingStarted {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
HttpServer server = vertx.createHttpServer()
.requestHandler(req -> req.response()
.setStatusCode(200)
.putHeader("content-type", "text/plain")
.endAndForget("Hello from Mutiny!"))
.listenAndAwait(8080);
System.out.println("Server listening on port " + server.actualPort());
WebClient client = WebClient.create(vertx, new WebClientOptions()
.setDefaultPort(8080)
.setDefaultHost("localhost"));
HttpResponse<String> response = client.get("/")
.as(BodyCodec.string())
.sendAndAwait();
System.out.println("Response: " + response.body());
vertx.closeAndAwait();
}
}
import io.vertx.core.Vertx;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.codec.BodyCodec;
public class GettingStarted {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.createHttpServer()
.requestHandler(req -> req.response()
.setStatusCode(200)
.putHeader("content-type", "text/plain")
.end("Hello from Vert.x!"))
.listen(8080)
.compose(server -> {
System.out.println("Server listening on port " + server.actualPort());
WebClient client = WebClient.create(vertx, new WebClientOptions()
.setDefaultPort(8080)
.setDefaultHost("localhost"));
return client.get("/")
.as(BodyCodec.string())
.send();
})
.onSuccess(response ->
System.out.println("Response: " + response.body()))
.onComplete(v -> vertx.close());
}
}
What is happening here
Vertx.vertx()creates a Mutiny-based Vert.x instance.listenAndAwait(8080)starts the server and blocks the calling thread until the server is ready. Under the hood it subscribes to theUni<HttpServer>returned bylisten()and awaits its result.sendAndAwait()sends the HTTP request and blocks until the response arrives: again a convenience wrapper around aUni.closeAndAwait()shuts down the Vert.x instance.
Using explicit reactive operators
The *AndAwait() helpers are convenient for scripts and tests, but in production code you will typically compose operations with Mutiny operators.
Here is the same WebClient call expressed reactively:
Note the use of onItem().transform() rather than shorthand aliases: this project favours explicit operator names so that the pipeline reads clearly.
Use io.vertx.mutiny.* imports
Always import classes from the io.vertx.mutiny.* packages, not from io.vertx.core.*.
The Mutiny classes are generated shims that wrap the Vert.x core classes and expose Uni / Multi return types instead of Future.
Next steps
- Uni and Multi: learn how
FutureandReadStreammap to Mutiny types. - Type Mapping: understand how Vert.x types are converted in the generated bindings.
- Error Handling: handle failures and use Vert.x expectations with Mutiny.
- Available Modules: see the full list of generated client modules.