Inleiding tot Vert.x

1. Overzicht

In dit artikel bespreken we Vert.x, behandelen we de kernconcepten en maken we er een eenvoudige RESTfull-webservice mee.

We beginnen met het behandelen van de basisconcepten van de toolkit, gaan langzaam verder met een HTTP-server en bouwen vervolgens de RESTfull-service.

2. Over Vert.x

Vert.x is een open source, reactieve en meertalige toolkit voor softwareontwikkeling van de ontwikkelaars van Eclipse.

Reactief programmeren is een programmeerparadigma, geassocieerd met asynchrone streams, die reageren op veranderingen of gebeurtenissen.

Evenzo gebruikt Vert.x een eventbus om te communiceren met verschillende delen van de applicatie en geeft het events asynchroon door aan handlers wanneer deze beschikbaar zijn.

We noemen het polyglot vanwege de ondersteuning voor meerdere JVM- en niet-JVM-talen zoals Java, Groovy, Ruby, Python en JavaScript.

3. Installatie

Om Vert.x te gebruiken, moeten we de Maven-afhankelijkheid toevoegen:

 io.vertx vertx-core 3.4.1 

De laatste versie van de afhankelijkheid is hier te vinden.

3. Verticles

Verticles zijn stukjes code die de Vert.x-engine uitvoert. De toolkit biedt ons veel abstracte verticale klassen, die kunnen worden uitgebreid en geïmplementeerd zoals we willen.

Omdat het polyglot is, kunnen verticles in elk van de ondersteunde talen worden geschreven. Een toepassing bestaat doorgaans uit meerdere verticles die in dezelfde Vert.x-instantie draaien en met elkaar communiceren via gebeurtenissen via de gebeurtenisbus.

Om een ​​verticle in JAVA te maken, moet de klasse io.vertx.core.Verticle interface, of een van zijn subklassen.

4. Evenementbus

Het is het zenuwstelsel van elke Vert.x-toepassing.

Omdat ze reactief zijn, blijven verticles inactief totdat ze een bericht of gebeurtenis ontvangen. Verticles communiceren met elkaar via de evenementenbus. Het bericht kan van alles zijn, van een string tot een complex object.

De berichtafhandeling is idealiter asynchroon, berichten worden in de wachtrij geplaatst op de gebeurtenisbus en de besturing wordt teruggestuurd naar de afzender. Later wordt het in de wachtrij geplaatst. Het antwoord wordt verzonden met Toekomst en Bel terug methoden.

5. Eenvoudige Vert.x-applicatie

Laten we een eenvoudige applicatie maken met een verticale lijn en deze implementeren met een vertx voorbeeld. Om onze verticale lijn te creëren, breiden we de

Om onze verticale lijn te creëren, breiden we de io.vertx.core.AbstractVerticle class en overschrijf de begin() methode:

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

De begin() methode wordt aangeroepen door de vertx bijvoorbeeld wanneer de verticle wordt ingezet. De methode duurt io.vertx.core.Future als parameter, die kan worden gebruikt om de status van een asynchrone ontplooiing van de verticle te ontdekken.

Laten we nu de verticale lijn inzetten:

openbare statische leegte hoofd (String [] args) {Vertx vertx = Vertx.vertx (); vertx.deployVerticle (nieuwe HelloVerticle ()); }

Evenzo kunnen we de hou op() methode van de AbstractVerticle class, die zal worden aangeroepen tijdens het afsluiten van de verticle:

@Override public void stop () {LOGGER.info ("Toepassing afsluiten"); }

6. HTTP-server

Laten we nu een HTTP-server opstarten met behulp van een verticaal:

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

We hebben het begin() methode om een ​​HTTP-server te maken en er een verzoekbehandelaar aan vast te maken. De requestHandler () methode wordt elke keer dat de server een verzoek ontvangt, aangeroepen.

Ten slotte is de server gebonden aan een poort en een AsyncResult handler wordt doorgegeven aan de luister() methode ongeacht of de verbinding of het opstarten van de server is geslaagd met toekomst. compleet () of toekomst.fail () in het geval van fouten.

Let daar op: config.getInteger () methode, leest de waarde voor de HTTP-poortconfiguratie die wordt geladen vanaf een extern conf.json het dossier.

Laten we onze server testen:

@Test openbare leegte whenReceivedResponse_thenSuccess (TestContext testContext) {Async async = testContext.async (); vertx.createHttpClient () .getNow (port, "localhost", "/", response -> {response.handler (responseBody -> {testContext.assertTrue (responseBody.toString (). bevat ("Hallo")); async. compleet(); }); }); }

Laten we voor de test vertx-unit gebruiken samen met JUnit .:

 io.vertx vertx-unit 3.4.1 test 

We kunnen de laatste versie hier downloaden.

De verticle is ingezet en in een vertx instantie in de opstelling() methode van de unit-test:

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

Evenzo is het vertx instantie is gesloten in de @AfterClass tearDown () methode:

@After openbare leegte tearDown (TestContext testContext) {vertx.close (testContext.asyncAssertSuccess ()); }

Merk op dat de @BeforeClass setup () methode duurt een TestContext argument. Dit helpt bij het beheersen en testen van het asynchrone gedrag van de test. De verticale implementatie is bijvoorbeeld asynchroon, dus in principe kunnen we niets testen, tenzij het correct is geïmplementeerd.

We hebben een tweede parameter voor de deployVerticle () methode, testContext.asyncAssertSuccess (). Tit wordt gebruikt om te weten of de server correct is geïmplementeerd of dat er fouten zijn opgetreden. Het wacht op de future.complete () of future.fail () in de serververticle die moet worden aangeroepen. In het geval van een storing, slaagt het niet voor de test.

7. RESTful WebService

We hebben een HTTP-server gemaakt, laten we die nu gebruiken om een ​​RESTfull WebService te hosten. Om dit te doen hebben we een andere Vert.x-module nodig met de naam vertx-web. Dit geeft bovendien veel extra functies voor webontwikkeling vertx-core.

Laten we de afhankelijkheid toevoegen aan onze pom.xml:

 io.vertx vertx-web 3.4.1 

We kunnen de laatste versie hier vinden.

7.1. Router en Routes

Laten we een router voor onze webservice. Deze router neemt een eenvoudige route van de GET-methode en de handlermethode getArtilces ():

Routerrouter = Router.router (vertx); router.get ("/ api / baeldung / artikelen / artikel /: id") .handler (dit :: getArticles);

De getArticle () methode is een eenvoudige methode die nieuw retourneert Artikel voorwerp:

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

EEN Router, wanneer hij een verzoek ontvangt, zoekt naar de overeenkomende route en geeft het verzoek verder door. De routes met een bijbehorende handlermethode om alles met het verzoek te doen.

In ons geval roept de handler de getArticle () methode. Het ontvangt de routingContext object als argument. Leidt de padparameter af ID kaart, en maakt een Artikel bezwaar ermee.

Laten we in het laatste deel van de methode de antwoord () methode op de routingContext object en plaats de headers, stel de HTTP-antwoordcode in en beëindig het antwoord met behulp van het gecodeerde JSON artikel voorwerp.

7.2. Toevoegen Router Naar server

Laten we nu het router, aangemaakt in de vorige sectie naar de HTTP-server:

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

Merk op dat we hebben toegevoegd requestHandler (router :: accepteren) naar de server. Dit instrueert de server om het aanvaarden() van de router bezwaar maken wanneer een verzoek wordt ontvangen.

Laten we nu onze webservice testen:

@Test openbare ongeldige gegevenId_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 (). bevat ("\" id \ ": \" 12345 \ "")); async.complete ();});}); }

8. Verpakken Vert.x Applicatie

Om de applicatie te verpakken als een inzetbaar Java Archive (.jar), gebruiken we de Maven Shade-plug-in en de configuraties in de executie label:

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

In de manifestEntries, Main-Verticle geeft het startpunt van de applicatie aan en de Hoofdklasse is een Vert.x-klasse die de vertx instantie en implementeert het Main-Verticle.

9. Conclusie

In dit inleidende artikel hebben we de Vert.x-toolkit en zijn fundamentele concepten besproken. Zag hoe je een HTTP-server moest maken, met Vert.x en ook een RESTFull WebService en liet zien hoe je ze kunt testen met vertx-eenheid.

Eindelijk de applicatie verpakt als een uitvoerbare jar.

De volledige implementatie van de codefragmenten is beschikbaar op GitHub.