1. Gambaran keseluruhan
Dalam artikel ini, kita akan membincangkan Vert.x, merangkumi konsep utamanya dan membuat perkhidmatan web RESTfull yang ringkas dengannya.
Kita akan mulakan dengan merangkumi konsep asas mengenai toolkit, perlahan-lahan beralih ke pelayan HTTP dan kemudian membina perkhidmatan RESTfull.
2. Mengenai Vert.x
Vert.x adalah alat pembangunan perisian sumber terbuka, reaktif dan poliglot dari pembangun Eclipse.
Pengaturcaraan reaktif adalah paradigma pengaturcaraan, yang berkaitan dengan aliran tak segerak, yang bertindak balas terhadap perubahan atau peristiwa.
Begitu juga, Vert.x menggunakan bas acara, untuk berkomunikasi dengan bahagian aplikasi yang berlainan dan menyampaikan acara, secara asinkron kepada pengendali apabila tersedia.
Kami menyebutnya poliglot kerana sokongannya untuk berbilang bahasa JVM dan bukan JVM seperti Java, Groovy, Ruby, Python, dan JavaScript.
3. Persediaan
Untuk menggunakan Vert.x kita perlu menambahkan kebergantungan Maven:
io.vertx vertx-core 3.4.1
Versi ketergantungan terkini boleh didapati di sini.
3. Vertikel
Verticles adalah potongan kod yang dijalankan oleh mesin Vert.x. Kit alat ini memberi kami banyak kelas vertikal abstrak, yang dapat diperluas, dan dilaksanakan seperti yang kami inginkan.
Sebagai poliglot, vertikal dapat ditulis dalam mana-mana bahasa yang disokong. Aplikasi biasanya terdiri daripada beberapa vertikal yang berjalan dalam instance Vert.x yang sama dan berkomunikasi antara satu sama lain menggunakan acara melalui bus acara.
Untuk membuat vertikal dalam JAVA, kelas mesti melaksanakan antara muka io.vertx.core.Verticle , atau salah satu subkelasnya.
4. Bas Acara
Ini adalah sistem saraf dari sebarang aplikasi Vert.x.
Bersikap reaktif, vertikel tetap tidak aktif sehingga mereka menerima mesej atau peristiwa. Vertikel saling berkomunikasi melalui bas acara. Mesej boleh berupa apa sahaja dari rentetan ke objek yang kompleks.
Pengendalian mesej idealnya tidak segerak, mesej diatur ke bas acara, dan kawalan dikembalikan kepada pengirim. Kemudian ia diserahkan ke vertikel pendengaran. Respons dihantar menggunakan kaedah Future dan callback .
5. Aplikasi Vert.x Mudah
Mari buat aplikasi sederhana dengan vertikal dan terapkan menggunakan instance vertx . Untuk membuat vertikel kita, kita akan memanjangkan
Untuk membuat vertikel kami, kami akan melanjutkan kelas io.vertx.core.AbstractVerticle dan mengatasi kaedah start () :
public class HelloVerticle extends AbstractVerticle { @Override public void start(Future future) { LOGGER.info("Welcome to Vertx"); } }
Kaedah permulaan () akan dipanggil oleh titik verteks ketika vertikel digunakan. Kaedah ini mengambil io.vertx.core.Future sebagai parameter, yang boleh digunakan untuk mengetahui status penyebaran vertikal asinkron.
Sekarang mari kita gunakan vertikal:
public static void main(String[] args) { Vertx vertx = Vertx.vertx(); vertx.deployVerticle(new HelloVerticle()); }
Begitu juga, kita boleh mengganti kaedah stop () dari kelas AbstractVerticle , yang akan dipanggil semasa menutup vertikal:
@Override public void stop() { LOGGER.info("Shutting down application"); }
6. Pelayan HTTP
Sekarang mari kita buat pelayan HTTP menggunakan vertikal:
@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 mengatasi kaedah start () untuk membuat pelayan HTTP dan melampirkan pengendali permintaan padanya. Kaedah requestHandler () dipanggil setiap kali pelayan menerima permintaan.
Akhirnya, pelayan terikat ke port, dan pengendali AsyncResult diteruskan ke kaedah listen () sama ada sambungan atau permulaan pelayan berjaya menggunakan future.complete () atau future.fail () sekiranya berlaku kesilapan.
Perhatikan bahawa: config.getInteger () , adalah membaca nilai untuk konfigurasi port HTTP yang dimuat dari fail conf.json luaran .
Mari uji pelayan kami:
@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 ujian, mari gunakan unit vertx bersama dengan JUnit:
io.vertx vertx-unit 3.4.1 test
Kami boleh mendapatkan versi terkini di sini.
Vertikel digunakan dan dalam keadaan vertx dalam kaedah setup () ujian unit:
@Before public void setup(TestContext testContext) { vertx = Vertx.vertx(); vertx.deployVerticle(SimpleServerVerticle.class.getName(), testContext.asyncAssertSuccess()); }
Begitu juga, contoh vertx ditutup dalam kaedah @AfterClass tearDown () :
@After public void tearDown(TestContext testContext) { vertx.close(testContext.asyncAssertSuccess()); }
Perhatikan bahawa kaedah @BeforeClass setup () mengambil argumen TestContext . Ini membantu dalam mengawal dan menguji tingkah laku asinkron ujian. Sebagai contoh, penyebaran vertikal tidak segerak, jadi pada dasarnya kita tidak dapat menguji apa-apa kecuali ia digunakan dengan betul.
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 pendahuluan ini, kami membincangkan kit alat Vert.x dan konsep asasnya. Melihat bagaimana membuat dan pelayan HTTP, dengan Vert.x dan juga RESTFull WebService dan menunjukkan cara mengujinya menggunakan unit vertx .
Akhirnya membungkus aplikasi sebagai balang yang boleh dilaksanakan.
Pelaksanaan lengkap potongan kode boleh didapati di GitHub.