Introdução ao Vert.x

Introdução ao Vert.x

1. Visão geral

Neste artigo, discutiremosVert.x, cobriremos seus principais conceitos e criaremos um serviço Web RESTfull simples com ele.

Vamos começar cobrindo os conceitos básicos sobre o kit de ferramentas, avançar lentamente para um servidor HTTP e, em seguida, construir o serviço RESTfull.

2. Sobre Vert.x

Vert.x is an open source, reactive and polyglot software development toolkit dos desenvolvedores do Eclipse.

A programação reativa é um paradigma de programação associado a fluxos assíncronos, que respondem a quaisquer alterações ou eventos.

Da mesma forma, o Vert.x usa um barramento de eventos para se comunicar com diferentes partes do aplicativo e passa eventos de forma assíncrona para os manipuladores, quando disponíveis.

Nós o chamamos de poliglota devido ao seu suporte para várias linguagens JVM e não JVM, como Java, Groovy, Ruby, Python e JavaScript.

3. Configuração

Para usar o Vert.x, precisamos adicionar a dependência do Maven:


    io.vertx
    vertx-core
    3.4.1

A versão mais recente da dependência pode ser encontradahere.

3. Vértices

Vértices são partes de código que o mecanismo Vert.x executa. O kit de ferramentas nos fornece muitas classes de verticle abstratas, que podem ser estendidas e implementadas como queremos.

Sendo poliglota, os vértices podem ser escritos em qualquer um dos idiomas suportados. Um aplicativo normalmente seria composto de vários vértices em execução na mesma instância do Vert.x e se comunicaria usando eventos por meio do barramento de eventos.

Para criar um verticle em JAVA, a classe deve implementar a interfaceio.vertx.core.Verticle, ou qualquer uma de suas subclasses.

4. Barramento de Eventos

É o sistema nervoso de qualquer aplicação Vert.x.

Sendo reativos, os vértices permanecem inativos até receberem uma mensagem ou evento. Os vértices se comunicam através do barramento de eventos. A mensagem pode ser qualquer coisa, de uma sequência a um objeto complexo.

O tratamento de mensagens é idealmente assíncrono, as mensagens são enfileiradas no barramento de eventos e o controle é retornado ao remetente. Mais tarde, é retirado da fila para o verticle de escuta. A resposta é enviada usando os métodosFutureecallback.

5. Aplicativo Vert.x Simples

Let’s create a simple application with a verticle and deploy it using a vertx instance. Para criar nosso verticle, vamos estender o

Para criar nosso verticle, vamos estender a classeio.vertx.core.AbstractVerticle e substituir o métodostart():

public class HelloVerticle extends AbstractVerticle {

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

O métodostart() será chamado pela instânciavertx quando o verticle for implantado. O método levaio.vertx.core.Future como parâmetro, que pode ser usado para descobrir o status de uma implantação assíncrona do verticle.

Agora vamos implantar o verticle:

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

Da mesma forma, podemos substituir o métodostop() da classeAbstractVerticle, que será invocado durante o encerramento do vertical:

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

6. Servidor HTTP

Agora, vamos ativar um servidor HTTP usando um 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());
          }
      });
}

Substituímos o métodostart() para criar um servidor HTTP e anexamos um manipulador de solicitação a ele. O métodorequestHandler() é chamado sempre que o servidor recebe uma solicitação.

Finalmente, o servidor é vinculado a uma porta e um manipuladorAsyncResult<HttpServer> é passado para o métodolisten(), quer a conexão ou inicialização do servidor seja bem-sucedida ou não usandofuture.complete() oufuture.fail() no caso de erros.

Observe que: métodoconfig.getInteger(), está lendo o valor para a configuração da porta HTTP que está sendo carregada de um arquivoconf.json externo.

Vamos testar nosso servidor:

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

Para o teste, vamos usar vertx-unit junto com JUnit .:


    io.vertx
    vertx-unit
    3.4.1
    test

Podemos obter a versão mais recentehere.

O verticle é implantado e em uma instânciavertx no métodosetup() do teste de unidade:

@Before
public void setup(TestContext testContext) {
    vertx = Vertx.vertx();

    vertx.deployVerticle(SimpleServerVerticle.class.getName(),
      testContext.asyncAssertSuccess());
}

Da mesma forma, a instânciavertx é fechada no método@AfterClass tearDown():

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

Observe que o método@BeforeClass setup() leva um argumentoTestContext. Isso ajuda a controlar e testar o comportamento assíncrono do teste. Por exemplo, a implantação vertical é assíncrona, então basicamente não podemos testar nada a menos que seja implantado corretamente.

Temos um segundo parâmetro para o métododeployVerticle(),testContext.asyncAssertSuccess().This é usado para saber se o servidor está implantado corretamente ou se ocorreu alguma falha. Ele aguarda a chamada defuture.complete() or future.fail() no vertical do servidor. No caso de uma falha, falha no teste.

7. RESTful WebService

Criamos um servidor HTTP, agora vamos usá-lo para hospedar um serviço Web RESTfull. Para fazer isso, precisaremos de outro módulo Vert.x chamadovertx-web. Isso fornece muitos recursos adicionais para desenvolvimento web além devertx-core.

Vamos adicionar a dependência ao nossopom.xml:


    io.vertx
    vertx-web
    3.4.1

Podemos encontrar a versão mais recentehere.

7.1. Router eRoutes

Vamos criar umrouter para nosso WebService. Este roteador seguirá uma rota simples de método GET e método manipuladorgetArtilces():

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

O métodogetArticle() é um método simples que retorna o novo objetoArticle:

private void getArticles(RoutingContext routingContext) {
    String articleId = routingContext.request()
      .getParam("id");
    Article article = new Article(articleId,
      "This is an intro to vertx", "example", "01-02-2017", 1578);

    routingContext.response()
      .putHeader("content-type", "application/json")
      .setStatusCode(200)
      .end(Json.encodePrettily(article));
}

ARouter, quando recebe uma solicitação, procura a rota correspondente e passa a solicitação adiante. Oroutes tendo um método de tratamento associado a ele para fazer a soma da solicitação.

Em nosso caso, o manipulador invoca o métodogetArticle(). Ele recebe o objetoroutingContext como um argumento. Deriva o parâmetro de caminhoid,e cria um objetoArticle com ele.

Na última parte do método, vamos invocar o métodoresponse() no objetoroutingContexte colocar os cabeçalhos, definir o código de resposta HTTP e finalizar a resposta usando o objetoarticle codificado em JSON .

7.2. AdicionandoRouter ao servidor

Agora vamos adicionar orouter, criado na seção anterior ao servidor HTTP:

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

Observe que adicionamosrequestHandler(router::accept) ao servidor. Isso instrui o servidor a invocaraccept() do objetorouter quando qualquer solicitação for recebida.

Agora vamos testar nosso WebService:

@Test
public void givenId_whenReceivedArticle_thenSuccess(TestContext testContext) {
    Async async = testContext.async();

    vertx.createHttpClient()
      .getNow(8080, "localhost", "/api/example/articles/article/12345",
        response -> {
            response.handler(responseBody -> {
            testContext.assertTrue(
              responseBody.toString().contains("\"id\" : \"12345\""));
            async.complete();
        });
      });
}

8. Empacotando o aplicativo Vert.x

Para empacotar o aplicativo como um Java Archive (.jar) implantável, vamos usar o plugin Maven Shade e as configurações na tagexecution:


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

EmmanifestEntries,Main-Verticle indica o ponto de partida do aplicativo eMain-Class é uma classe Vert.x que cria a instânciavertxe implanta oMain-Verticle.

9. Conclusão

Neste artigo introdutório, discutimos o kit de ferramentas Vert.x e seus conceitos fundamentais. Viu como criar um servidor HTTP, com Vert.x e também um WebService RESTFull e mostrei como testá-los usandovertx-unit.

Finalmente empacotou o aplicativo como um jar executável.

A implementação completa dos snippets de código está disponívelover on GitHub.