Vert.x microservices: an (opinionated) application

Victor Gil
5 min readJan 15, 2019

--

First of all, sorry for the tautology in the title, a library can be either opinionated or un-opinionated (such as Vert.x is), but an application can only be opinionated. However, I decided to include “opinionated” to help getting my point across even though is redundant.

The Motivation

I am a big fan of Vert.x and the official documentation is quite good, yet it is not straight-forward to understand how it works and how to use it.
There are a lot of blogs and articles describing Vert.x terminology and its concurrency model.
There are also tons of “Hello World” Vert.x applications on Github, and the rest seem to be just variations of the already typical “Web chat application using Vert.x”.
On top of that, many of them are outdated (using AngularJS instead of Angular2+, for example).

The only two exceptions which I found are:
vertx-microservices-workshop: a demo application by the Vert.x development team.
ngrx-realtime-app: proof of concept application focused on state management which just updates a shared counter.

Those are good example applications and I am thankful to the authors for sharing with the community.
However, one problem I have with them is that the source code of all the microservices is put together in the same repository (I guess for the sake of simplicity).
I am not trying to be a purist, but for me, the main requisites of a microservice is that it must be independently deployed, upgraded and run, which basically means that each microservice should have its own version string and its own code repository.
Also, each microservice should have a well defined (contracted) API. And regarding APIs, JSON is good… for JavaScript, but for Java (and other statically-typed languages for that matter) there is something better (I warned you this was going to be an opinionated post ☺): Google Protocol Buffers, but I am getting ahead of myself…

And one more thing, the devil is in the details, and these applications avoid dealing with “boring” stuff such as basic security (HTTPS configuration), which leaves information gaps for these important topics.

So in short, I was lacking a comprehensive and non-trivial (yet simple) microservices application based on Vert.x, and since I believe the best way of learning is to roll up one’s sleeves and code, I wrote one in my spare time.

And then, after I had already written almost all of this post (and completed my example microservices application), I found this: vertx-blueprint-microservice, which is almost what I was looking for (despite of being monorepo). But it seems to be going through a major refactoring which has not been completed after two years and it actually looks outdated (the frontend is still based on AngularJS).

The Code

I have just “released” (umbrella) version 2.0.0.0 of my example application (this previous post presented the first version), which is composed of six different Github repositories:

mylocation-backend version 1.1.0.0 → main microservice and API gateway.
mylocation-last_known_location version 1.0.0.0 → another microservice, including its protobuf API.
mylocation-last_known_location-persistence version 1.0.0.0 → yet another microservice, also including its own protobuf API.

vertx-utility-extensions version 1.0.0.0 → library used by the previous three microservices to avoid boilerplate code when starting and initializing Vert.x.

mylocation-android version 1.0 → Android application which sends live location data messages to mylocation-backend.

mylocation-frontend version 1.1.0 → Angular 7 application which asynchronously displays either live location data (if possible) or the latest previously saved location.

If you think that having to manage and push commits to 6 different source code repositories involves quite a lot of hassle, you are totally right, but I do believe the advantages overcome the disadvantages (more on that in a future post). Again, this is my opinion, and please note that it is not based on irrational fads but on years of experience.
And of course, I am always happy to change my mind whenever facts, circumstances or enlightening discussions show me a better way☺.

I mentioned Google Protocol Buffers before because all the communication between the Java microservices is done through protobuf binary encoding, not only for better performance but also because of the automatic generation of the required API classes.
And for the sake of modularisation, each protobuf API is built separately into its own Maven (jar) artifact.

The communication between the backend and the frontend is done through JSON though, since I did not want to deal with protobuf in JavaScript/TypeScript.
For similar reasons the communication between the Android client app and the backend also uses JSON.

Please note that currently, despite using clustered Vert.x instances, all the microservices are meant to run on the same host (for the sake of simplicity), I plan to change that in the future.

And one comment about the coding style, as soon as the implementation of a Handler grew bigger than a few lines, I decided to create a new class in a separated file instead of an anonymous class or a lambada expression.
I prefer that because I like methods (and classes) to be small, as a direct consequence of applying the Single Responsibility Principle.

The Functionality

Ok, so what does the application do?
When a new Web client connects, the event bus bridge is set up, then the latest saved location (previously sent by my mobile phone to the backend) is requested, retrieved (through the event bus bridge) and displayed. Simultaneously (everything is asynchronous), it starts listening for live location updates again on the Vert.x event bus bridge, and as soon as the live updates start coming (through server push), they replace the saved location on the display.

The app is up and running on a small Amazon Lightsail VM (1GB RAM), so you may see it in action yourself: http://mylocation.devaction.net

Final Thoughts

I could write much more on related topics such as:
— How I combined Vert.x and Spring in the backend (please don’t freak out, I just use Spring purely for dependency injection, I dislike Spring gigantic ecosystem as a whole, specially Spring Boot — again, just my opinion).
— The Android service which fetches the location provided by the GPS.
— The Vert.x service which saves each received location in a local file (in binary format) since it is not efficient to use a database just for that.
— The related Vert.x service which provides that saved location.
— Client-side certificate (in Android) in addition to server-side.
— The application configuration (resolving and loading properties values, password encryption).
— RxJS usage in the frontend.
— The Vert.x event bus SockJS bridge.
— How “WINCH” Linux signal is used to gracefully shutdown Vert.x
—The social implications of sharing my live location with potentially everybody (spoiler alert: I introduced a “masking” security mechanism in the Android code to keep the area where I live under the radar).

But again, I will leave that for future posts, in any case, everything is in the code, so feel free to peek at it on Github or ask me☺.

Originally published at www.devaction.net.

--

--