What's new in Vert.x 4.3
Vert.x 4.3 comes with plenty of new exciting features.
Here is an overview of the most important features in Vert.x 4.3.
Web Client URI templates
URI templates provide an alternative to HTTP request string URIs based on the URI Template RFC.
A Vert.x URI template can be created as follows:
A web client can use it to send a request:
URI templates expansion mechanism takes care of encoding parameter values. It can also handle lists and maps.
Several expansion styles are available for each relevant part of a URI.
Json Schema
Json Schema validation has received a major update. In 4.3, we introduce support for more drafts:
- Draft 4 (used by Swagger and OpenAPI 3.0)
- Draft 7 (generally used by many services)
- Draft 2019-09
- Draft 2020-12 (used by OpenAPI 3.1)
This refactoring required that the previous implementation was deprecated and will be replaced with a polyglot friendly alternative. In a nutshell, the new API can be used as follows:
This work lays the foundation for future support of OpenAPI in vertx-web.
Vert.x gRPC
Until 4.3, Vert.x gRPC support was built on top of gRPC Netty. It worked very well but with some friction: Netty versions had to be matched and often forced, which lead to incompatibilities with Vert.x Web, etc.
The new gRPC stack for Vert.x gets rid of those limitations and provides a set of new exclusive features built on top of the Vert.x HTTP/2 stack.
Beyond implementing the gRPC stub model, Vert.x gRPC has a request/response API.
This API can also be used with protobuf data instead of decoded protobuf, giving the opportunity to easily build gRPC proxies with Vert.x:
Notice that the proxy does not need to reference generated stubs at any time. It works universally for any gRPC service.
The proxy can forward compressed messages without intermediate decompression if the proxied server supports compression.
Finally, the Vert.x gRPC server can be used within a Vert.x Web router:
Extra HTTP compression algorithms
Vert.x HTTP servers can now compress to Brotli and Zstandard in addition to GZIP.
Vert.x HTTP client can now decompress Brotli in addition to GZIP.
Vertx Web
Figuring out the right order for handlers can be sometimes tricky.
In 4.3, we now check the order when multiple handlers are added under the same route. Incorrect setups are signaled.
For example, adding a user handler before a body handler will raise an error:
The validation will verify that handlers are added in the following order:
PLATFORM
: platform handlers (LoggerHandler
,FaviconHandler
, etc.)SECURITY_POLICY
: HTTP Security policies (CSPHandler
,CorsHandler
, etc.)BODY
: Body parsing (BodyHandler
)AUTHENTICATION
: Authn (JWTAuthHandler
,APIKeyHandler
,WebauthnHandler
, etc.)INPUT_TRUST
: Input verification (CSRFHandler
)AUTHORIZATION
: Authz (AuthorizationHandler
)
If your handler is performing any specific task, you can mark it as any of these by adding the marker interface to your implementation.
In addition, security handlers using callbacks now ensure that callbacks are added in the right order, relieving from creating temporary objects:
Previously, a reference to the callback route had to be created before the oauth2 handler was added. Otherwise, the callback handler would be shaded.
This feature applies to all security handlers that use callbacks. For example, OAuth2
, OTP
, and Webauthn
.
Other notable improvements
Other small improvements were on processing the body of the request. We now cache the body which avoids parsing its
content on each ctx.getBodyAsXXX()
invocation and finally, BodyHandler
will now respect the HTTP directive
Expect: Continue
when processing uploads, informing clients that they are allowed to start uploading if validation
is correct.
MySQL client pipelining support
The reactive MySQL client now supports pipelining like its elder brother the reactive PostgreSQL client.
Reactive Microsoft SQL Server client
Cursors and streaming
The Reactive Microsoft SQL Server client supports cursor fetching and streaming like the PostgreSQL and MySQL client.
For example, you can create a RowStream
using from a PreparedStatement
:
More data types
Starting with this release, it is possible to read from and write to columns of the following types:
varbinary(max)
text
/ntext
image
User experience improvements in Shared Data and Event Bus areas
ClusterSerializable
as a public API member
The interface io.vertx.core.shareddata.impl.ClusterSerializable
has been made public.
In previous versions, it was in an implementation package and this had discouraged some users to rely on it.
If you didn’t know, types implementing ClusterSerializable
can be shared in async maps.
More types supported
In this version, it is possible to share objects of types java.io.Serializable
or io.vertx.core.shareddata.ClusterSerializable
in shared data maps and on the Event Bus.
For safety reasons though, only approved classes are allowed to be encoded and decoded as message bodies on the Event Bus.
For example, this is how to control which Serializable
classes can be allowed:
Dynamic codec lookup
When sending a message on the Event Bus, Vert.x uses the codec specified in DeliveryOptions
or chooses one based on the message body type.
In this version, it is possible to choose a registered codec when Vert.x has not been able to select one:
This can solve a few use cases, for example:
- selecting a codec that does nothing for objects to deliver locally if you know the object is immutable
- you have many objects generated from
.proto
files and want to defer to Protocol Buffers for serialization/deserialization - you want to use Jackson Databind for any object
Kafka 3
Our Vert.x Kafka Client has been upgraded to use Apache Kafka Client 3.0