Vert.x Event Bus
Event bus messaging — point-to-point, pub/sub, request-reply, codecs, clustering.
# CLAUDE.md — Vert.x Event Bus
## What it is
- An in-process (and optionally cluster-wide) message bus baked into Vert.x.
- Decouples senders from receivers — verticles communicate by **address** (a string), not by Java references.
- Works in three modes:
- **Point-to-point** — one consumer receives.
- **Pub/Sub** — all consumers receive.
- **Request/Reply** — sender gets a response.
## Sending messages
```java
EventBus eb = vertx.eventBus();
// Point-to-point
eb.send("orders.create", new JsonObject().put("userId", "123"));
// Pub/Sub
eb.publish("user.created", new JsonObject().put("id", "123"));
// Request/Reply
eb.request("orders.find", "order-123").onSuccess(reply -> {
log.info("got order: {}", reply.body());
});
```
- Addresses are simple strings. Use a hierarchical convention: `orders.create`, `orders.cancel`, `users.update`.
- Don't put PII or large payloads in event-bus messages — they're broadcast across the cluster.
## Consuming
```java
eb.consumer("orders.create", message -> {
JsonObject body = (JsonObject) message.body();
OrderId id = createOrder(body);
message.reply(new JsonObject().put("id", id.toString()));
});
```
- Always reply on a request — if you don't, the sender gets a timeout.
- Use `message.fail(code, msg)` to signal an error to the sender.
- Unsubscribe via the `MessageConsumer` returned by `consumer(...)` when shutting down.
## Codecs
- Default codecs: `String`, `JsonObject`, `JsonArray`, `Buffer`, primitive boxed types.
- For custom POJOs, register a codec:
```java
eb.registerDefaultCodec(MyDto.class, new MyDtoCodec());
```
- For cluster mode, all nodes must register the same codecs. Otherwise messages won't deserialize.
## Clustering
- Vert.x can cluster across nodes via Hazelcast, Infinispan, Ignite, or ZooKeeper.
- The same `EventBus` API works locally and in cluster mode.
- For cluster mode: `Vertx.clusteredVertx(options, ar -> ...)`.
- Network split-brain handling: configure the underlying clustering layer carefully. Defaults are not production-ready.
## Patterns
- **Service-locator alternative**: register handlers as services on the bus instead of injecting them.
- **Saga orchestration**: each step publishes an event; coordinator listens and dispatches the next step.
- **Cache invalidation**: publish on `cache.invalidate.{key}`; every node consumes and updates its local cache.
## Performance
- In-process: ~1–10 µs per message.
- Clustered: depends on the cluster manager. Hazelcast adds ~1 ms per hop.
- For high throughput, batch messages or use direct verticle calls instead of the event bus.
## Service proxies
- Vert.x can generate type-safe proxies for an interface — calls become event-bus messages under the hood:
```java
@ProxyGen
public interface UserService {
void findById(String id, Handler<AsyncResult<JsonObject>> handler);
}
```
- Generated code (annotation processor) creates the proxy and the codec.
- Useful for cross-language clients in clustered setups.
## Don't
- Don't use the event bus for high-throughput hot paths between two verticles in the same JVM. Direct method calls are faster.
- Don't broadcast sensitive data on a clustered bus without encryption (`SSLContext` on the cluster manager).
- Don't forget to reply on `request` consumers. Senders will time out.
- Don't use mutable shared objects as message bodies. Use immutable JSON or POJOs with codecs.
Other Vert.x templates
Modern Vert.x Rules
Vert.x 4+ defaults: verticles, event loop discipline, and the golden rule.
Vert.x Web Routing
Vert.x Web router, sub-routers, body handler, validation, and error handling.
Vert.x with Mutiny (Reactive)
Mutiny Uni/Multi over the callback API — composable reactive workflows.
Vert.x + Reactive Postgres
Vertx-pg-client for fully reactive Postgres access — pooling, prepared queries, transactions.