Introduktion till Vert.x

1. Översikt

I den här artikeln kommer vi att diskutera Vert.x, täcka dess kärnkoncept och skapa en enkel RESTfull webbtjänst med den.

Vi börjar med att täcka grundkoncepten om verktygslådan, sakta gå vidare till en HTTP-server och sedan bygga RESTfull-tjänsten.

2. Om Vert.x

Vert.x är en öppen källkod, reaktiv och mångsidig programvaruutvecklingsverktygssats från utvecklarna av Eclipse.

Reaktiv programmering är ett programmeringsparadigm, associerat med asynkrona strömmar, som svarar på eventuella förändringar eller händelser.

På samma sätt använder Vert.x en händelsebuss för att kommunicera med olika delar av applikationen och vidarebefordra händelser asynkront till hanterare när de är tillgängliga.

Vi kallar det polyglot på grund av dess stöd för flera JVM- och icke-JVM-språk som Java, Groovy, Ruby, Python och JavaScript.

3. Inställning

För att använda Vert.x måste vi lägga till Maven-beroendet:

 io.vertx vertx-core 3.4.1 

Den senaste versionen av beroendet finns här.

3. Vertiklar

Vertiklar är bitar av kod som Vert.x-motorn kör. Verktygssatsen ger oss många abstrakta vertikalklasser, som kan förlängas och implementeras som vi vill.

Att vara polyglot kan vertikaler skrivas på något av de språk som stöds. En applikation skulle vanligtvis bestå av flera vertikaler som körs i samma Vert.x-instans och kommunicera med varandra med hjälp av händelser via händelsebussen.

För att skapa en verticle i JAVA måste klassen implementera io.vertx.core.Verticle- gränssnittet eller någon av dess underklasser.

4. Event Bus

Det är nervsystemet i alla Vert.x-applikationer.

Att vara reaktiva förblir vertikala vilande tills de får ett meddelande eller händelse. Vertikaler kommunicerar med varandra via evenemangsbussen. Meddelandet kan vara allt från en sträng till ett komplext objekt.

Meddelandehantering är idealiskt asynkron, meddelanden köas till händelsebussen och kontroll returneras till avsändaren. Senare är det dequued till lyssnande verticle. Svaret skickas med hjälp av framtida och återuppringningsmetoder .

5. Enkel Vert.x-applikation

Låt oss skapa en enkel applikation med en vertikel och distribuera den med en vertx- instans . För att skapa vår vertikala förlänger vi

För att skapa vår vertikala förlänger vi klassen io.vertx.core.AbstractVerticle och åsidosätter start () -metoden:

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

Den start () metoden kommer att anropas av VertX exempel när verticle är utvecklad. Metoden tar io.vertx.core.Future som en parameter, som kan användas för att upptäcka status för en asynkron distribution av vertikalen.

Låt oss nu distribuera vertikalen:

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

På samma sätt kan vi åsidosätta stop () -metoden från klassen AbstractVerticle , som kommer att åberopas när vi stänger av vertikalen:

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

6. HTTP-server

Låt oss nu snurra upp en HTTP-server med hjälp av en 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()); } }); }

Vi har åsidosatt start () -metoden för att skapa en HTTP-server och bifogat en begäranhanterare till den. Den requestHandler () Metoden kallas varje gång servern tar emot en begäran.

Slutligen är servern bunden till en port, och en AsyncResult- hanterare skickas till listen () -metoden oavsett om anslutningen eller servern startas med hjälp av future.complete () eller future.fail () i fallet med någon fel.

Observera att: config.getInteger () -metoden läser värdet för HTTP-portkonfiguration som laddas från en extern conf.json- fil.

Låt oss testa vår server:

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

För testet, låt oss använda vertx-enhet tillsammans med JUnit .:

 io.vertx vertx-unit 3.4.1 test 

Vi kan få den senaste versionen här.

Vertikalen distribueras och i vertx- instans i setup () -metoden för enhetstestet:

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

På samma sätt stängs vertx- instansen i metoden @AfterClass tearDown () :

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

Observera att metoden @BeforeClass setup () tar ett TestContext- argument. Detta hjälper till att kontrollera och testa testets asynkrona beteende. Till exempel är vertikaldistributionen asynkroniserad, så i princip kan vi inte testa någonting om den inte har distribuerats korrekt.

Vi har en andra parameter till metoden deployVerticle () , testContext.asyncAssertSuccess (). Detta används för att veta om servern har distribuerats korrekt eller om några fel inträffat. Det väntar på att future.complete () eller future.fail () i serverhörnan ska anropas. I händelse av ett misslyckande misslyckas testet.

7. RESTful WebService

Vi har skapat en HTTP-server, kan nu använda den för att vara värd för RESTfull WebService. För att göra det behöver vi en annan Vert.x-modul som heter vertx-web . Detta ger en hel del ytterligare funktioner för webbutveckling ovanpå vertx-core .

Låt oss lägga till beroendet i vår pom.xml:

 io.vertx vertx-web 3.4.1 

Vi hittar den senaste versionen här.

7.1. Router och rutter

Låt oss skapa en router för vår WebService. Denna router tar en enkel väg för GET-metoden och hanteringsmetoden getArtilces () :

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

Den getArticle () metoden är en enkel metod att avkastningen ny artikel objekt:

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

En router, när den tar emot en begäran, letar efter den matchande rutten och skickar begäran vidare. De linjer som har en hanterare metod i samband med den att göra sumthing med begäran.

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

I den här inledningsartikeln diskuterade vi Vert.x-verktygssatsen och dess grundläggande begrepp. Såg hur man skapar och HTTP-server, med Vert.x och även en RESTFull WebService och visade hur man testar dem med vertx-unit .

Slutligen packade applikationen som en körbar burk.

Den fullständiga implementeringen av kodavsnitten finns på GitHub.