Introduction à Vert.x

1. Vue d’ensemble

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

Nous allons commencer par couvrir les concepts de base de la boîte à outils, puis passer progressivement à un serveur HTTP, puis créer le service RESTfull.

2. À propos de Vert.x

  • Vert.x est un toolkit de développement logiciel open source, réactif et polyglotte ** développé par les développeurs d’Eclipse.

La programmation réactive est un paradigme de programmation, associé à des flux asynchrones, qui répondent aux changements ou aux événements.

De la même manière, 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 s’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. Installer

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

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>3.4.1</version>
</dependency>

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

3. Verticules

Les verticules 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 mises en œuvre à volonté

Étant polyglottes, les verticules peuvent être écrits dans n’importe laquelle des langues supportées. Une application serait généralement composée de plusieurs verticules 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 rayon dans JAVA, la classe doit implémenter l’interface io.vertx.core.Verticle , ou l’une de ses sous-classes.

4. Bus de l’événement

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

Réactifs, les vertices restent en sommeil jusqu’à ce qu’ils reçoivent un message ou un événement. Les verticules communiquent les uns avec les autres via le bus de l’événement. 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é du vertige à l’écoute. La réponse est envoyée à l’aide des méthodes Future et callback .

5. Application Vert.x simple

  • Créons une application simple avec une verticale et déployez-la à l’aide d’une instance de vertx ** . Pour créer notre section verticale, nous étendrons le

Pour créer notre section verticale, 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<Void> future) {
        LOGGER.info("Welcome to Vertx");
    }
}

La méthode start () sera invoquée par l’occurrence vertx lors du déploiement du cercle vertical. La méthode prend io.vertx.core.Future en tant que paramètre, qui peut être utilisé pour découvrir le statut d’un déploiement asynchrone de la verticale.

Maintenant, déployons le cercle vertical:

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

De même, nous pouvons redéfinir la méthode stop () à partir de la classe AbstractVerticle , qui sera invoquée lors de la fermeture du verticule:

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

6. Serveur HTTP

Maintenant, démarrons un serveur HTTP en utilisant un cercle vertical:

@Override
public void start(Future<Void> 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 redéfini la méthode start () pour créer un serveur HTTP et lui avons associé un gestionnaire de demandes. La méthode requestHandler () est appelée à chaque fois que le serveur reçoit une demande.

Enfin, le serveur est lié à un port et un gestionnaire AsyncResult <HttpServer> est transmis à la méthode listen () , que la connexion ou le démarrage du serveur ait réussi ou non à l’aide de future.complete () ou future.fail ( ) en cas d’erreur.

Notez que la méthode config.getInteger () lit la valeur de la configuration du port HTTP en cours de chargement à 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:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-unit</artifactId>
    <version>3.4.1</version>
    <scope>test</scope>
</dependency>

Nous pouvons obtenir la dernière version here .

Le verticule est déployé et dans une instance 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 @ BeforeClass setup () prend un argument TestContext . Cela aide à contrôler et à tester le comportement asynchrone du test. Par exemple, le déploiement de la colonne vertébrale est asynchrone. En principe, nous ne pouvons rien tester s’il n’est pas déployé correctement.

Nous avons un deuxième paramètre à la méthode deployVerticle () , testContext.asyncAssertSuccess () . _T , qui permet de savoir si le serveur est déployé correctement ou en cas de défaillance. Il attend que la fonction future.complete () ou future.fail () _ de la section du serveur soit appelée. En cas d’échec, le test échoue.

7. WebService RESTful

Nous avons créé un serveur HTTP. Utilisons-le maintenant pour héberger un WebService RESTfull. Pour ce faire, nous aurons besoin d’un autre module Vert.x appelé vertx-web . Cela donne beaucoup de fonctionnalités supplémentaires pour le développement Web en plus de vertx-core .

Ajoutons la dépendance à notre pom.xml:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>3.4.1</version>
</dependency>

Nous pouvons trouver la dernière version here .

7.1. Router et Routes

Créons un routeur pour notre WebService. Ce routeur suivra un itinéraire simple de la méthode GET et de la méthode de gestionnaire getArtilces () :

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

La méthode getArticle () est une méthode simple qui renvoie un nouvel objet Article :

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));
}

Un routeur, lorsqu’il reçoit une demande, recherche l’itinéraire correspondant et transmet ensuite la demande. Le routes ayant une méthode de gestionnaire associée pour faire quelque chose avec la requête.

Dans notre cas, le gestionnaire appelle la méthode getArticle () . Il reçoit l’objet routingContext en tant qu’argument. Dérive le paramètre de chemin id, et crée un objet Article avec ce dernier.

Dans la dernière partie de la méthode, appelons la méthode response () sur l’objet routingContext et mettons les en-têtes, définissez le code de réponse HTTP et terminez la réponse à l’aide de l’objet article codé JSON.

7.2. Ajout de Router au serveur

Ajoutons maintenant le router, créé dans la section précédente sur le serveur HTTP:

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

accept) au serveur. Cela indique au serveur d’appeler le accept () de l’objet router__ lorsqu’une requête est reçue.

Maintenant, testons notre 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. Application d’emballage Vert.x

Pour conditionner l’application en tant qu’archive Java déployable (.jar), utilisons le plug-in Maven Shade et les configurations de la balise execution :

<configuration>
    <transformers>
        <transformer
          implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <manifestEntries>
                <Main-Class>io.vertx.core.Starter</Main-Class>
                <Main-Verticle>com.baeldung.SimpleServerVerticle</Main-Verticle>
            </manifestEntries>
        </transformer>
    </transformers>
    <artifactSet/>
    <outputFile>
        ${project.build.directory}/${project.artifactId}-${project.version}-app.jar
    </outputFile>
</configuration>

Dans les manifestEntries, Main-Verticle indique le point de départ de l’application et la Main-Class est une classe Vert.x qui crée l’instance vertx et déploie le Main-Verticle.

9. Conclusion

Dans cet article d’introduction, nous avons abordé le toolkit Vert.x et ses concepts fondamentaux. Nous avons vu comment créer un serveur HTTP, avec Vert.x ainsi qu’un WebService RESTFull et montré comment les tester avec vertx-unit .

Finalement emballé l’application comme un fichier jar exécutable.

L’implémentation complète des extraits de code est disponible sur over sur GitHub .