Introduction à Vert.x

1. Vue d'ensemble

Dans cet article, nous discuterons de Vert.x, couvrirons ses concepts de base et créerons un service Web RESTfull simple avec.

Nous commencerons par couvrir les concepts de base de la boîte à outils, avancer lentement vers un serveur HTTP, puis créer le service RESTfull.

2. À propos de Vert.x

Vert.x est une boîte à outils de développement logiciel open source, réactive et polyglotte des développeurs d'Eclipse.

La programmation réactive est un paradigme de programmation, associé à des flux asynchrones, qui répondent à tout changement ou événement.

De même, Vert.x utilise un bus d'événements, pour communiquer avec différentes parties de l'application et transmet les événements, de manière asynchrone aux gestionnaires lorsqu'ils sont disponibles.

Nous l'appelons polyglotte en raison de sa prise en charge de plusieurs langages JVM et non JVM tels que Java, Groovy, Ruby, Python et JavaScript.

3. Configuration

Pour utiliser Vert.x, nous devons ajouter la dépendance Maven:

 io.vertx vertx-core 3.4.1 

La dernière version de la dépendance peut être trouvée ici.

3. Verticules

Les verticles sont des morceaux de code que le moteur Vert.x exécute. La boîte à outils nous fournit de nombreuses classes de verticules abstraites, qui peuvent être étendues et implémentées comme nous le voulons.

Étant polyglottes, les verticules peuvent être écrits dans n'importe laquelle des langues prises en charge. Une application serait généralement composée de plusieurs sommets s'exécutant dans la même instance Vert.x et communiquerait entre eux à l'aide d'événements via le bus d'événements.

Pour créer un verticle dans JAVA, la classe doit implémenter l' interface io.vertx.core.Verticle , ou l'une de ses sous-classes.

4. Bus d'événements

C'est le système nerveux de toute application Vert.x.

Étant réactifs, les verticules restent en sommeil jusqu'à ce qu'ils reçoivent un message ou un événement. Les verticules communiquent entre eux via le bus d'événements. Le message peut être n'importe quoi, d'une chaîne à un objet complexe.

La gestion des messages est idéalement asynchrone, les messages sont mis en file d'attente sur le bus d'événements et le contrôle est renvoyé à l'expéditeur. Plus tard, il est retiré de la file d'attente du sommet d'écoute. La réponse est envoyée à l'aide des méthodes Future et de rappel .

5. Application Vert.x simple

Créons une application simple avec un verticle et déployons-la en utilisant une instance de vertx . Pour créer notre verticle, nous allons étendre le

Pour créer notre verticle, nous allons étendre la classe io.vertx.core.AbstractVerticle et remplacer la méthode start () :

public class HelloVerticle extends AbstractVerticle { @Override public void start(Future future) { LOGGER.info("Welcome to Vertx"); } }

La méthode start () sera invoquée par l' instance de vertx lorsque le verticle est déployé. La méthode prend io.vertx.core.Future comme paramètre, qui peut être utilisé pour découvrir l'état d'un déploiement asynchrone du verticle.

Déployons maintenant le verticle:

public static void main(String[] args) { Vertx vertx = Vertx.vertx(); vertx.deployVerticle(new HelloVerticle()); }

De même, nous pouvons remplacer la méthode stop () de la classe AbstractVerticle , qui sera appelée lors de l'arrêt du verticle:

@Override public void stop() { LOGGER.info("Shutting down application"); }

6. Serveur HTTP

Maintenant, faisons tourner un serveur HTTP en utilisant un verticle:

@Override public void start(Future future) { vertx.createHttpServer() .requestHandler(r -> r.response().end("Welcome to Vert.x Intro"); }) .listen(config().getInteger("http.port", 9090), result -> { if (result.succeeded()) { future.complete(); } else { future.fail(result.cause()); } }); }

Nous avons remplacé la méthode start () pour créer un serveur HTTP et y avons attaché un gestionnaire de requêtes. La méthode requestHandler () est appelée chaque fois que le serveur reçoit une requête.

Enfin, le serveur est lié à un port et un gestionnaire AsyncResult est passé à la méthode listen () , que la connexion ou le démarrage du serveur réussisse ou non en utilisant future.complete () ou future.fail () dans le cas de tout les erreurs.

Notez que: la méthode config.getInteger () lit la valeur de la configuration du port HTTP qui est chargée à partir d'un fichier conf.json externe .

Testons notre serveur:

@Test public void whenReceivedResponse_thenSuccess(TestContext testContext) { Async async = testContext.async(); vertx.createHttpClient() .getNow(port, "localhost", "/", response -> { response.handler(responseBody -> { testContext.assertTrue(responseBody.toString().contains("Hello")); async.complete(); }); }); }

Pour le test, utilisons vertx-unit avec JUnit:

 io.vertx vertx-unit 3.4.1 test 

Nous pouvons obtenir la dernière version ici.

Le verticle est déployé et dans une instance de vertx dans la méthode setup () du test unitaire:

@Before public void setup(TestContext testContext) { vertx = Vertx.vertx(); vertx.deployVerticle(SimpleServerVerticle.class.getName(), testContext.asyncAssertSuccess()); }

De même, l' instance vertx est fermée dans la méthode @AfterClass tearDown () :

@After public void tearDown(TestContext testContext) { vertx.close(testContext.asyncAssertSuccess()); }

Notez que la méthode setup () @BeforeClass prend un argument TestContext . Cela permet de contrôler et de tester le comportement asynchrone du test. Par exemple, le déploiement vertical est asynchrone, nous ne pouvons donc rien tester à moins qu'il ne soit déployé correctement.

We have a second parameter to the deployVerticle() method, testContext.asyncAssertSuccess(). This is used to know if the server is deployed correctly or any failures occurred. It waits for the future.complete() or future.fail() in the server verticle to be called. In the case of a failure, it fails the test.

7. RESTful WebService

We have created an HTTP server, lets now use that to host an RESTfull WebService. In order do so we will need another Vert.x module called vertx-web. This gives a lot of additional features for web development on top of vertx-core.

Let's add the dependency to our pom.xml:

 io.vertx vertx-web 3.4.1 

We can find the latest version here.

7.1. Router and Routes

Let's create a router for our WebService. This router will take a simple route of GET method, and handler method getArtilces():

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

The getArticle() method is a simple method that returns new Article object:

private void getArticles(RoutingContext routingContext) { String articleId = routingContext.request() .getParam("id"); Article article = new Article(articleId, "This is an intro to vertx", "baeldung", "01-02-2017", 1578); routingContext.response() .putHeader("content-type", "application/json") .setStatusCode(200) .end(Json.encodePrettily(article)); }

A Router, when receives a request, looks for the matching route, and passes the request further. The routes having a handler method associated with it to do sumthing with the request.

In our case, the handler invokes the getArticle() method. It receives the routingContext object as an argument. Derives the path parameter id, and creates an Article object with it.

In the last part of the method, let's invoke the response() method on the routingContext object and put the headers, set the HTTP response code, and end the response using the JSON encoded article object.

7.2. Adding Router to Server

Now let's add the router, created in the previous section to the HTTP server:

vertx.createHttpServer() .requestHandler(router::accept) .listen(config().getInteger("http.port", 8080), result -> { if (result.succeeded()) { future.complete(); } else { future.fail(result.cause()); } });

Notice that we have added requestHandler(router::accept) to the server. This instructs the server, to invoke the accept() of the router object when any request is received.

Now let's test our WebService:

@Test public void givenId_whenReceivedArticle_thenSuccess(TestContext testContext) { Async async = testContext.async(); vertx.createHttpClient() .getNow(8080, "localhost", "/api/baeldung/articles/article/12345", response -> { response.handler(responseBody -> { testContext.assertTrue( responseBody.toString().contains("\"id\" : \"12345\"")); async.complete(); }); }); }

8. Packaging Vert.x Application

To package the application as a deployable Java Archive (.jar) let's use Maven Shade plugin and the configurations in the execution tag:

    io.vertx.core.Starter com.baeldung.SimpleServerVerticle      ${project.build.directory}/${project.artifactId}-${project.version}-app.jar  

In the manifestEntries, Main-Verticle indicates the starting point of the application and the Main-Class is a Vert.x class which, creates the vertx instance and deploys the Main-Verticle.

9. Conclusion

Dans cet article d'introduction, nous avons discuté de la boîte à outils Vert.x et de ses concepts fondamentaux. J'ai vu comment créer un serveur HTTP, avec Vert.x et aussi un WebService RESTFull et comment les tester à l'aide de vertx-unit .

Enfin empaqueté l'application sous forme de fichier jar exécutable.

L'implémentation complète des extraits de code est disponible à l'adresse over sur GitHub.