1. 概要

この記事では、 Vert.x について説明し、そのコアコンセプトをカバーし、それを使用して単純なRESTfullWebサービスを作成します。

まず、ツールキットに関する基本的な概念について説明し、ゆっくりとHTTPサーバーに進んでから、RESTfullサービスを構築します。

2. Vert.xについて

Vert.xは、Eclipseの開発者によるオープンソースのリアクティブで多言語のソフトウェア開発ツールキットです。

リアクティブプログラミングは、変更やイベントに応答する非同期ストリームに関連付けられたプログラミングパラダイムです。

同様に、Vert.xはイベントバスを使用してアプリケーションのさまざまな部分と通信し、イベントが利用可能な場合は非同期でハンドラーに渡します。

複数のJVMおよびJava、Groovy、Ruby、Python、JavaScriptなどの非JVM言語をサポートしているため、これをポリグロットと呼びます。

3. 設定

Vert.xを使用するには、Maven依存関係を追加する必要があります。

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>3.4.1</version>
</dependency>

依存関係の最新バージョンはここにあります。

3. 頂点

Verticlesは、Vert.xエンジンが実行するコードの一部です。 ツールキットは、必要に応じて拡張および実装できる多くの抽象バーティクルクラスを提供します。

ポリグロットであるため、バーティクルはサポートされている任意の言語で記述できます。 アプリケーションは通常、同じVert.xインスタンスで実行されている複数のバーティクルで構成され、イベントバスを介してイベントを使用して相互に通信します。

JAVAでバーティクルを作成するには、クラスはio.vertx.core.Verticleインターフェースまたはそのサブクラスのいずれかを実装する必要があります。

4. イベントバス

これは、Vert.xアプリケーションの神経系です。

反応性があるため、バーティクルはメッセージまたはイベントを受信するまで休止状態のままです。 頂点は、イベントバスを介して相互に通信します。 メッセージは、文字列から複雑なオブジェクトまで、何でもかまいません。

メッセージ処理は理想的には非同期であり、メッセージはイベントバスにキューイングされ、制御は送信者に返されます。 後で、リスニングバーティクルにデキューされます。 応答は、Futureおよびcallbackメソッドを使用して送信されます。

5. シンプルなVert.xアプリケーション

バーティクルを使用して単純なアプリケーションを作成し、vertxインスタンスを使用してデプロイしましょう。 頂点を作成するために、

頂点を作成するには、 io.vertx.core.AbstractVerticle クラスを拡張し、 start()メソッドをオーバーライドします。

public class HelloVerticle extends AbstractVerticle {

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

start()メソッドは、バーティクルが展開されたときにvertxインスタンスによって呼び出されます。 このメソッドは、 io.vertx.core.Future をパラメーターとして受け取ります。これを使用して、バーティクルの非同期展開のステータスを検出できます。

次に、バーティクルをデプロイしましょう。

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

同様に、 AbstractVerticleクラスのstop()メソッドをオーバーライドできます。これは、バーティクルのシャットダウン中に呼び出されます。

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

6. HTTPサーバー

次に、バーティクルを使用してHTTPサーバーを起動しましょう。

@Override
public void start(Future<Void> 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());
          }
      });
}

start()メソッドをオーバーライドしてHTTPサーバーを作成し、それにリクエストハンドラーをアタッチしました。 requestHandler()メソッドは、サーバーがリクエストを受信するたびに呼び出されます。

最後に、サーバーはポートにバインドされ、 AsyncResult ハンドラーはに渡されます聞く() 接続またはサーバーの起動が成功したかどうかを使用するメソッド future.complete() また future.fail() エラーが発生した場合。

注: config.getInteger() methodは、外部conf.jsonファイルからロードされているHTTPポート構成の値を読み取っています。

サーバーをテストしてみましょう。

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

テストには、vertx-unitをJUnitと一緒に使用してみましょう。

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-unit</artifactId>
    <version>3.4.1</version>
    <scope>test</scope>
</dependency>

最新バージョンはこちらで入手できます。

単体テストのsetup()メソッドで、バーティクルがデプロイされ、vertxインスタンスに配置されます。

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

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

同様に、 vertx インスタンスは、 @AfterClass tearDown()メソッドで閉じられます。

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

@BeforeClass setup()メソッドがTestContext引数を取ることに注意してください。 これは、テストの非同期動作の制御とテストに役立ちます。 たとえば、バーティクルのデプロイは非同期であるため、正しくデプロイされない限り、基本的に何もテストできません。

2番目のパラメータがあります deployVerticle() 方法、 testContext.asyncAssertSuccess()。 T これは、サーバーが正しくデプロイされているかどうか、または障害が発生したかどうかを知るために使用されます。 サーバーバーティクルのfuture.complete()またはfuture.fail()が呼び出されるのを待ちます。 失敗した場合、テストに失敗します。

7. RESTfulWebサービス

HTTPサーバーを作成しました。これを使用して、RESTfullWebServiceをホストします。 そのためには、vertx-webという別のVert.xモジュールが必要になります。 これにより、vertx-coreに加えてWeb開発のための多くの追加機能が提供されます。

pom.xml:に依存関係を追加しましょう

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>3.4.1</version>
</dependency>

最新バージョンはこちらでご覧いただけます。

7.1. ルーターおよびルート

Webサービス用のルーターを作成しましょう。 このルーターは、GETメソッドとハンドラーメソッド getArtilces()の単純なルートを取ります。

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

getArticle()メソッドは、新しいArticleオブジェクトを返す単純なメソッドです。

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

ルーターは、リクエストを受信すると、一致するルートを探し、リクエストをさらに渡します。 ルートには、リクエストを合計するためのハンドラーメソッドが関連付けられています。

この場合、ハンドラーは getArticle()メソッドを呼び出します。 routingContextオブジェクトを引数として受け取ります。 パスパラメータid、を導出し、それを使用してArticleオブジェクトを作成します。

メソッドの最後の部分では、 routingContextオブジェクトでresponse()メソッドを呼び出し、ヘッダーを配置し、HTTP応答コードを設定し、JSONエンコードを使用して応答を終了します。 記事オブジェクト。

7.2. サーバーへのルーターの追加

次に、前のセクションで作成したルーターをHTTPサーバーに追加しましょう。

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

requestHandler(router :: accept)をサーバーに追加したことに注意してください。 これは、要求を受信したときに routerオブジェクトのaccept()を呼び出すようにサーバーに指示します。

それでは、Webサービスをテストしてみましょう。

@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. Vert.xアプリケーションのパッケージ化

アプリケーションをデプロイ可能なJavaアーカイブ(.jar)としてパッケージ化するには、MavenShadeプラグインとexecutionタグの構成を使用します。

<configuration>
    <transformers>
        <transformer 
          implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <manifestEntries>
                <Main-Class>io.vertx.core.Starter</Main-Class>
                <Main-Verticle>com.baeldung.SimpleServerVerticle</Main-Verticle>
            </manifestEntries>
        </transformer>
    </transformers>
    <artifactSet />
    <outputFile>
        ${project.build.directory}/${project.artifactId}-${project.version}-app.jar
    </outputFile>
</configuration>

manifestEntriesでMain-Verticle はアプリケーションの開始点を示し、Main-Classを作成するVert.xクラスです。 vertx インスタンスを作成し、Main-Verticleをデプロイします。

9. 結論

この紹介記事では、Vert.xツールキットとその基本的な概念について説明しました。 Vert.xとRESTFullWebServiceを使用してHTTPサーバーを作成する方法を確認し、vertx-unitを使用してそれらをテストする方法を示しました。

最後に、アプリケーションを実行可能jarとしてパッケージ化しました。

コードスニペットの完全な実装は、GitHubから入手できます。