Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Overview

In this quick article, we'll discuss the integration of Spring with Vert-x and leverage the best of both worlds: the powerful and well-known Spring feature, and the reactive single-event loop from Vert.x.

To understand more about Vert.x, please refer to our introductory article here.

2. Setup

First, let's get our dependencies in place:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>3.4.1</version>
</dependency>

Notice that we've excluded the embedded Tomcat dependency from spring-boot-starter-web since we are going to deploy our services using verticles.

You may find the latest dependencies here.

3. Spring Vert.x Application

Now, we'll build a sample application with two verticles deployed.

The first Verticle routes requests to the handler that sends them as messages to the given address. The other Verticle listens at a given address.

Let's look at these in action.

3.1. Sender Verticle

ServerVerticle accepts HTTP requests and sends them as messages to a designated address. Let's create a ServerVerticle class extending the AbstractVerticle, and override the start() method to create our HTTP Server:

@Override
public void start() throws Exception {
    super.start();

    Router router = Router.router(vertx);
    router.get("/api/baeldung/articles")
      .handler(this::getAllArticlesHandler);

    vertx.createHttpServer()
      .requestHandler(router::accept)
      .listen(config().getInteger("http.port", 8080));
}

In the server request handler, we passed a router object, which redirects any incoming request to the getAllArticlesHandler handler:

private void getAllArticlesHandler(RoutingContext routingContext) {
    vertx.eventBus().<String>send(ArticleRecipientVerticle.GET_ALL_ARTICLES, "", 
      result -> {
        if (result.succeeded()) {
            routingContext.response()
              .putHeader("content-type", "application/json")
              .setStatusCode(200)
              .end(result.result()
              .body());
        } else {
            routingContext.response()
              .setStatusCode(500)
              .end();
        }
      });
}

In the handler method, we're passing an event to the Vert.x Event bus, with an event id as GET_ALL_ARTICLES. Then we process the callback accordingly for success and error scenarios.

The message from the event bus will be consumed by the ArticleRecipientVerticle, discussed in the following section.

3.2. Recipient Verticle

ArticleRecipientVerticle listens for incoming messages and injects a Spring bean. It acts as the rendezvous point for Spring and Vert.x.

We'll inject Spring service bean into a Verticle and invoke respective methods:

@Override
public void start() throws Exception {
    super.start();
    vertx.eventBus().<String>consumer(GET_ALL_ARTICLES)
      .handler(getAllArticleService(articleService));
}

Here, articleService is an injected Spring bean:

@Autowired
private ArticleService articleService;

This Verticle will keep listening to the event bus on an address GET_ALL_ARTICLES. Once it receives a message, it delegates it to the getAllArticleService handler method:

private Handler<Message<String>> getAllArticleService(ArticleService service) {
    return msg -> vertx.<String> executeBlocking(future -> {
        try {
            future.complete(
            mapper.writeValueAsString(service.getAllArticle()));
        } catch (JsonProcessingException e) {
            future.fail(e);
        }
    }, result -> {
        if (result.succeeded()) {
            msg.reply(result.result());
        } else {
            msg.reply(result.cause().toString());
        }
    });
}

This performs the required service operation and replies to the message with the status. The message reply is being referenced at the ServerVerticle and the callback result as we saw in the earlier section.

4. Service Class

The service class is a simple implementation, providing methods to interact with the repository layer:

@Service
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    public List<Article> getAllArticle() {
        return articleRepository.findAll();
    }
}

The ArticleRepository extends, org.springframework.data.repository.CrudRepository and provides basic CRUD functionalities.

5. Deploying Verticles

We will be deploying the application, just the way we would do for a regular Spring Boot application. We have to create a Vert.X instance, and deploy verticles in it, after the Spring context initialization in completed:

public class VertxSpringApplication {

    @Autowired
    private ServerVerticle serverVerticle;

    @Autowired
    private ArticleRecipientVerticle articleRecipientVerticle;

    public static void main(String[] args) {
        SpringApplication.run(VertxSpringApplication.class, args);
    }

    @PostConstruct
    public void deployVerticle() {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(serverVerticle);
        vertx.deployVerticle(articleRecipientVerticle);
    }
}

Notice that, we are injecting verticle instances into the Spring application class. So, we will have to annotate the Verticle classes,

So, we will have to annotate the Verticle classes, ServerVerticle and ArticleRecipientVerticle with @Component.

Let's test the application:

@Test
public void givenUrl_whenReceivedArticles_thenSuccess() {
    ResponseEntity<String> responseEntity = restTemplate
      .getForEntity("http://localhost:8080/api/baeldung/articles", String.class);
 
    assertEquals(200, responseEntity.getStatusCodeValue());
}

6. Conclusion

In this article, we learned about how to build a RESTful WebService using Spring and Vert.x.

As usual, the example is available over on GitHub.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until end-of-day today:

>> GET ACCESS NOW

Generic footer banner
Comments are closed on this article!