This project adds the flavor of SpringBoot's style annotations in vertx to reduce the learning curve. It follows the same annotation style as @RestController, @Service, @Autowired, @RequestParam, @RequestBody, @PostMapping and @GetMapping, whereas controller and service classes should extend AbstractVerticle as per the implementation of Vertx.
APACHE-2.0 License
This project adds the flavor of SpringBoot's style annotations in vertx to reduce the learning curve. It follows the same annotation style as @RestController, @Service, @Repository, @Autowired, @RequestParam, @RequestBody, @PostMapping and @GetMapping, whereas controller and service classes should extend AbstractVerticle as per the implementation of Vertx.
Vertx is an event-driven toolkit backed by the Eclipse Foundation. It's a polyglot and is used for highly concurrent code writing. When compared to Spring (Webflux or Boot), Vertx is exceptionally fast. In my performance testing, I found Vertx to be 75% faster than Spring. Techempower has also shared very similar results on their site: https://www.techempower.com/benchmarks/#section=data-r22. Now considering this, if you want to develop a state-of-the-art application with high throughput, one should go for vertx, as it is Java's fastest unopinionated framework available today (Techempower's results also back this statement).
In Vertx, a router needs to be declared in order to register API endpoints in the application. Each route has its own handler, which entertains the logic once the API endpoint is called. It becomes very hard to maintain so many route handlers, and since most people tend to declare all the routes in the same class, it's a very hard class to maintain.
allprojects {
repositories {
maven ("https://jitpack.io")
}
}
<repositories>
...
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
dependencies {
implementation ("com.github.Areeb-Gillani:vertx-boost:1.0.1")
}
<dependencies>
...
<dependency>
<groupId>com.github.Areeb-Gillani</groupId>
<artifactId>vertx-boost</artifactId>
<version>1.0.1</version>
</dependency>
</dependencies>
Vertx says that every class that extends AbstractVerticle will be handled by its own dedicated threads and thread pools and will have its own life cycle. I am assuming that you have the basic idea of MainVerticle and WorkerVerticle. If you don't have the idea, then please visit https://vertx.io first. A service is basically a worker verticle; you can configure it using the following JSON:
{
{...},
"workers":{
"ExampleWorker":{
"instance":5,
"poolSize":6
}
},
{...}
}
Add these lines for performance monitoring metrics enablement via Prometheus.
{
{...},
"metrics": {
"enabled": true,
"tool": "prometheus"
},
{...}
}
Booster, which is the initializing class of this utility, requires this JsonObject in the constructor in order to initialize.
Please initialize it in your main application class to run everything on startup.
public class Main extends BoostApplication {
public static void main(String[] args) {
run(Application.class, args);
}
}
@RestController
public class ExampleController extends AbstractController{
@GetMapping("/sayHi")
public String sayHi(){
return "hi";
}
@GetMapping("/sayHello")
public String sayHello(@RequestParam("username") String user){
return "Hello "+user;
}
@PostMapping("/sayHiToUser")
public String sayHiToUser(JsonObject body){
return "Hi! " +body.getString("username");
}
@PostMapping("/replyHiToUser")
public void replyHiToUser(JsonObject body, RoutingContext context){
eventBus.request("MyTopic", body, reply->{
if(reply.succeeded()){
context.json(reply.result().body());
}
});
}
@PostMapping("/MyTopic")
public void MyTopic(JsonObject body, HttpRequest request){
eventBus.request("MyTopic", body, request.getResponseHandler());
}
@PostMapping("/MyTopicViaStr")
public void MyTopicViaStr(String body, HttpRequest request){
eventBus.request("MyTopicViaStr", body, request.getResponseHandler());
}
@PostMapping("/MyTopicViaClass")
public void MyTopicViaClass(ClassA body, HttpRequest request){
eventBus.request("MyTopicViaClass", body, request.getResponseHandler());
}
}
@Service("ExampleWorker") // It is the same name that is described in configuration.
public class ExampleService extends AbstractService{
@Autowired
DatabaseRepo myRepo;
@Override
public void bindTopics(){
eventBus.consumer("MyTopic", this::replyHiToUser);
// In case of clustered mode on, you need to use clusteredEventBus.
// So that other microservices can discover this topic
// clusteredEventBus.consumer("MyTopic", this::replyHiToUser);
}
private void replyHiToUser(Message<Object> message){
JsonObject vertxJsonObject = (JsonObject) message;
message.reply("Hi "+ vertxJsonObject.getString("username"));
}
}
public class DatabaseRepo {
//Write your db operations here
}
If you want to use a dynamic, easy-to-use database library, then please check out vertx-boost-db. It will give you all the tools you need for databases, including CrudRepository, just like Spring.
@Repository("MyDbConfig")
public class DatabaseRepo extends CrudRepository<ExampleModel>{
public DatabaseRepo (String connectionName, JsonObject config){
super(connectionName, config);
}
//Write other db operations here your CRUD operations are already covered above
}
"MyDbConfig" will help you manage multi-tenancy at the database level. Read more on (https://github.com/Areeb-Gillani/vertx-boost-db/blob/main/README.md)