Module 10 · Executable guide
Vert.x Web & Data
REST routing, WebClient, PostgreSQL client, transaction, validation, streaming và testing.
1. Router
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.get("/users/:id").handler(this::getUser);
router.post("/orders").handler(this::createOrder);2. RoutingContext
void getUser(RoutingContext ctx) {
long id = Long.parseLong(ctx.pathParam("id"));
service.findUser(id)
.onSuccess(ctx::json)
.onFailure(err -> fail(ctx, err));
}3. Middleware
Request → BodyHandler → Correlation ID → Auth → Validation → Business Handler → Error Handler
4. WebClient
webClient.postAbs(paymentUrl)
.sendJsonObject(payload)
.compose(resp -> {
if (resp.statusCode() >= 500)
return Future.failedFuture("payment unavailable");
return Future.succeededFuture(resp.bodyAsJsonObject());
});5. PostgreSQL Client
pool.preparedQuery(
"SELECT id, user_id, status FROM orders WHERE id = $1")
.execute(Tuple.of(id))
.map(this::mapOrder);6. Transaction
pool.withTransaction(conn ->
conn.preparedQuery("UPDATE inventory SET reserved = reserved + $1 WHERE sku = $2")
.execute(Tuple.of(qty, sku))
.compose(v -> conn.preparedQuery("INSERT INTO orders(user_id,status) VALUES ($1,$2)")
.execute(Tuple.of(userId, "CREATED")))
);7. Validation
Phân biệt 400 validation, 404 missing, 409 conflict/idempotency và 503 downstream unavailable.
8. SSE
Theo dõi write queue và connection lifecycle; client chậm không được làm memory tăng vô hạn.
9. Testing
Deploy verticle thật trong integration test, setup DB fixture và gọi endpoint bằng WebClient.
10. Lab
- POST /orders validate JSON.
- Insert bằng prepared query.
- GET /orders/:id.
- Transaction reserve inventory + create order.
- WebClient timeout.
- Integration tests.