The vert.x is a tool-kit for building async applications on the JVM. Vert.x has a set of coure functions and a set of extensions for high level functions. The Vert.x core APIs are implemented in multiple languages including Scala. Vert.x-Web is a set of constructs for building web applications. Both the core and the web are embeddable.
The functions of Vert.x core include
- TCP/HTTP/WebSocket/UDP clients and servers, DNS client
- Event bus
- Shared data: local maps and clustered distributed maps
- Periodic and delayed actions
- Deploying and undeploying
- File system access
High leve functions such as db acess, authorization, web routing etc are in Vert.x extensions.
Vert.x is event-driven and uses serveral event loops, so called
Multi-Reactor Pattern. An event handler will be executed in the exact same loop thread. A Vert.x inscance maintains N (by default is
core * 2) event loop threads.
All Vert.x core APIs are asynchronouse except several file system operations ending in
executeBloding to run blocking operation. Calling it several times from the same context executes serially. Specifying
ordered = false makes to run them parallely. Another way is using a wroker verticle. Blocking code is executed on Vert.x work pool, additional pools can be created.
Vert.x use futures to coordinate async restuls.
Vert.x comes with an optional actor-like deployment and concurrency model. Verticles can be a standard verticle running in the vent loop thread or a worker verticle running in the worker thread pool.
If you embed Vert.x and finish with it, you can call
close to close it down. An event loop has a
Context that can be retrieved by
vertx.getOrCreateContext(). You can use
Context#runOnContext to run code in this context asynchornously. You can use
get to create context data shared by code in the same context.
A Vert.x instance has an event bus that forms a distributed p2p messaging system spanning mulitple verver nodes and multiple browsers. The event bus supports publish/subscribe, p2p, and request-response messaging.
Vert.x comes with a
JsonPointer to process JSON data.
Most data is shuffled around inside Vert.x using
2.1 Running Blocking Code
Vertx#executeBlocking to run blocking code. The method signature is as following:
It executes the
blockingCodeHandler on a worker pool thread. In the
blockingCodeHandler the current context remains the original context and therefore any task scheduled in it will be executed on the this context and not on the worker thread. By default, the
true and the blocking code is executed serially. If the
false, the blocking code is executed in parallel on the worker pool. The
resultHandler is called when the blocking code is completed.
resultHandler runs in the original context, i.e., the vertx message loop thread.
An alternative way to run blocking code is to use a woker verticle.
When the blocking operation lasts more than the 10 seconds, a message will be printed on the console by the blocked thread checker. Long blocking operations should use a dedicated thread managed by the application.
3 HTTP Server
3.1 A Simple Server
build.sc file. Vert.x V4 will support Scala 2.13.
You can set
HttpServerOptions to set the options such as compression, idle timeout etc.
The request has a type of
HttpServerResponse. It has many methods.
uri returns the URI such as
param1=abc¶m2=xyz. Other request methods include
MultiMap type that allows multiple values for the same case-insensitive key),
To receive body, use
request.handler(buffer -> ...). The handler is called every time a chunk of the request body arrives. It is possible to cache the buffer and process the whole in
getCookie to retrieve a cookie by name. Use
addCookie to add a cookie.
The response has a type of
HttpServerResponse that is obtained by
request.Response(). It is a
WriteStream that you can pipe to it from any
ReadStream. Some methods are:
wirte: needs to write
Content-Lengthfirst if you are not suing HTTP chunking.
end: can take a strin or a buffer.
setChunked: to send data when size is not known in advance.
sendFile: or open a file as an
AsyncFileand pipe it to the HTTP response, or
readFileand write it to the response.
A send file Java example:
4 Vert.x Web Example
5 Vert.x Web Features
The key features are
- Touting based on method, path, MIME types, etc.
- Sub-routers and reroute.
- Path matching by regular expreesion and path parmater extraction.
- Cookie parsing and handling.
- Session support.
- Error page handler.
- Auth handlers.
- Template engine support.
- CORS and CSRF support.
Router is the core concept of Vert.x-Web. A
Router has zero or more
Routes. A router takes an HTTP request and passes it to the first matching route. The router has a
handler associated with it. The handler can process the request, then either end it or pass it to the next matching handler. The next handler could be a hanlder in the same route or in another mathcing route. A handler takes a
RoutingContext that contains the standard Vert.x
HttpServerResponse. The same routing context instance is passed to all handlers of the same request.
For blocking code, use
blockingHandler to call the blocking handler. Set
ordered = false if the order of blocing code doesn’t matter. To process multipart form data, use a non-blocking handler first to call
Route matching is based on the method, path and MIME type of a request. You can specify the order of route matching.
You can set the path of a route using
route().path("/some/path"). The path can include a
* to match a path that has a certain prefix. Use
"/some/path/:param1/:param2" to capture a path parameter. Use
pathRegex to match path or capturing path parameters by regular expressions.
method(HttpMethod.Post) to match an HTTP
Post method. By default, a route matches all methods. You can also use
router.getWithRegex("*.some") to match a
Get method. To match multiple methods, call the
method multiple times.
produces method to specify matching MIME type – content-based routing.
content-type header in request. Wildcard char of
* is supported, for example:
router.route().consume("text/*"). You can match sub-type such as
produces method to specify the MIME type(s) to match the request
accept header. Both
produces can be called multiple times.
By default routes are matched in the order they are added to the router. Call the route’s
order method to define an order, a smaller number (can be negative) is called before a bigger number. Use the
last method to make a route to be the last.
5.2 Route Functions
enable a route.
RoutingContext#get to put and get data for the lifetime of the request.
RoutingContext#reroute("/some/path") to reroute a request. Use
RoutingContext to share data.
Use `Router.mountSubRouter(“/mount/path”, subRouter) to mount a subrouter.
Route match failures include
400 for unmatched path, unmatched method, unmatched response content type, unmatched request content type and empty body errors.
You can set failure handlers for any route. Failure routing will occur if a handler throws an exception (
500 failure), or if a handler calls
fail with an HTTP failure status code. Use
RoutingContext#failure to retrieve status code or the exception (the status code is
BodyHandler let you retrieve request bodies, limit body sizes and handle file uploads. It should be the first hanlder because the router needs to install handlers to consume HTTP reqeust body and this should be before executing any async call. If an async call must happen first, use
request.resume() before and after the async all. Use
getBodyAsJson to get JSON body,
getBodyAsString for sting body and
getBody to get a buffer. By default, form attributes are merged into request parameters.
RoutingContext#setCookie to get and set cookies. Vert.x-Web uses session cookies to identify a session. The cookie is just an UUID and the actuall session data is stored on the server. Local session stores are implemented by using a shared local map, and have a reaper which clears out expired sessions. Clustered session store uses a distributed map.
StaticHandler to serve static resources. The default static file directory is
webroot. It is configurable using
setWebRoot. It supports
TemplateHandler to call a
TemplateEngine. By default templates are located in
templates directory. The handler will return a result of rendering with a content type of
text/html by default.
ResponseContentTypeHandler can set the appriopriate
Content-Type of response based on the
accept of request.