Pengantar Vert.x

1. Ikhtisar

Pada artikel ini, kita akan membahas Vert.x, membahas konsep intinya dan membuat layanan web RESTfull sederhana dengannya.

Kami akan mulai dengan membahas konsep dasar tentang toolkit, perlahan-lahan bergerak maju ke server HTTP dan kemudian membangun layanan RESTfull.

2. Tentang Vert.x

Vert.x adalah perangkat pengembangan perangkat lunak open source, reaktif, dan poliglot dari pengembang Eclipse.

Pemrograman reaktif adalah paradigma pemrograman, yang terkait dengan aliran asinkron, yang merespons setiap perubahan atau peristiwa.

Demikian pula, Vert.x menggunakan bus peristiwa, untuk berkomunikasi dengan berbagai bagian aplikasi dan meneruskan peristiwa, secara asinkron ke penangan jika tersedia.

Kami menyebutnya polyglot karena dukungannya untuk beberapa bahasa JVM dan non-JVM seperti Java, Groovy, Ruby, Python, dan JavaScript.

3. Penyiapan

Untuk menggunakan Vert.x kita perlu menambahkan ketergantungan Maven:

 io.vertx vertx-core 3.4.1 

Versi terbaru dari ketergantungan tersebut dapat ditemukan di sini.

3. Vertikel

Vertikel adalah potongan kode yang dijalankan mesin Vert.x. Toolkit memberi kita banyak kelas verticle abstrak, yang dapat diperpanjang, dan diimplementasikan sesuai keinginan kita.

Menjadi poliglot, simpul dapat ditulis dalam salah satu bahasa yang didukung. Aplikasi biasanya akan terdiri dari beberapa vertikel yang berjalan dalam instance Vert.x yang sama dan berkomunikasi satu sama lain menggunakan acara melalui bus acara.

Untuk membuat verticle di JAVA, kelas harus mengimplementasikan antarmuka io.vertx.core.Verticle , atau salah satu subkelasnya.

4. Bus Acara

Ini adalah sistem saraf dari semua aplikasi Vert.x.

Menjadi reaktif, vertikel tetap tidak aktif sampai menerima pesan atau peristiwa. Verticles berkomunikasi satu sama lain melalui bus acara. Pesan dapat berupa apa saja, mulai dari string hingga objek kompleks.

Penanganan pesan idealnya tidak sinkron, pesan diantrekan ke event bus, dan kontrol dikembalikan ke pengirim. Nanti itu diantrekan ke verticle mendengarkan. Responsnya dikirim menggunakan metode Future dan callback .

5. Aplikasi Vert.x Sederhana

Mari buat aplikasi sederhana dengan verticle dan terapkan menggunakan instance vertx . Untuk membuat simpul kita, kita akan memperpanjang

Untuk membuat verticle kita, kita akan memperluas kelas io.vertx.core.AbstractVerticle dan mengganti metode start () :

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

Metode start () akan dipanggil oleh instance vertx saat verticle di-deploy. Metode ini menggunakan io.vertx.core.Future sebagai parameter, yang dapat digunakan untuk menemukan status penerapan asinkron dari verticle.

Sekarang mari kita terapkan verticle:

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

Demikian pula, kita bisa mengganti metode stop () dari kelas AbstractVerticle , yang akan dipanggil saat mematikan verticle:

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

6. Server HTTP

Sekarang mari kita putar server HTTP menggunakan 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()); } }); }

Kami telah menimpa metode start () untuk membuat server HTTP dan melampirkan penangan permintaan padanya. Metode requestHandler () dipanggil setiap kali server menerima permintaan.

Terakhir, server terikat ke port, dan penangan AsyncResult diteruskan ke metode listen () apakah koneksi atau startup server berhasil atau tidak menggunakan future.complete () atau future.fail () dalam kasus apa pun. kesalahan.

Perhatikan bahwa: metode config.getInteger () , membaca nilai untuk konfigurasi port HTTP yang dimuat dari file conf.json eksternal .

Mari kita uji server kita:

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

Untuk pengujian, mari gunakan unit-vertx bersama dengan JUnit .:

 io.vertx vertx-unit 3.4.1 test 

Kita bisa mendapatkan versi terbaru disini.

Verticle di-deploy dan dalam instance vertx dalam metode setup () dari pengujian unit:

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

Demikian pula, instance vertx ditutup dalam metode @AfterClass tearDown () :

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

Perhatikan bahwa metode @BeforeClass setup () mengambil argumen TestContext . Ini membantu dalam mengontrol dan menguji perilaku asynchronous dari pengujian. Misalnya, penerapan verticle adalah asinkron, jadi pada dasarnya kami tidak dapat menguji apa pun kecuali diterapkan dengan benar.

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

Dalam artikel pengantar ini, kami membahas toolkit Vert.x dan konsep dasarnya. Melihat cara membuat dan server HTTP, dengan Vert.x dan juga RESTFull WebService dan menunjukkan cara mengujinya menggunakan vertx-unit .

Akhirnya mengemas aplikasi sebagai jar yang dapat dieksekusi.

Implementasi lengkap dari potongan kode tersedia di GitHub.