1. 概要

Ratpack は、現代の高性能リアルタイムアプリケーション用に構築されたJVMベースのライブラリのセットです。 組み込みのNettyイベント駆動型ネットワークエンジンの上に構築されており、リアクティブデザインパターンに完全に準拠しています。

この記事では、Ratpackの使用方法を学び、それを使用して小さなアプリケーションを構築します。

2. なぜRatpackなのか?

Ratpackの主な利点:

  • 非常に軽量で、高速で、スケーラブルです
  • DropWizardなどの他のフレームワークよりも少ないメモリを消費します。 興味深いベンチマーク比較結果はここにあります。
  • Netty の上に構築されているため、Ratpackは完全にイベント駆動型であり、本質的に非ブロッキングです。
  • Guiceの依存関係管理をサポートしています
  • Spring Boot と同様に、Ratpackにはテストケースをすばやくセットアップするための独自のテストライブラリがあります。

3. アプリケーションの作成

Ratpackがどのように機能するかを理解するために、Ratpackを使用して小さなアプリケーションを作成することから始めましょう。

3.1. Mavenの依存関係

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

<dependency>
    <groupId>io.ratpack</groupId>
    <artifactId>ratpack-core</artifactId>
    <version>1.4.5</version>
</dependency>
<dependency>
    <groupId>io.ratpack</groupId>
    <artifactId>ratpack-test</artifactId>
    <version>1.4.5</version>
</dependency>

最新バージョンは、 Maven Centralで確認できます。

ビルドシステムとしてMavenを使用していますが、 Ratpackの推奨事項に従って、ビルドツールとして Gradle を使用することをお勧めします。これは、RatpackがRatpackのGradleプラグイン

次のビルドGradleスクリプトを使用できます。

buildscript {
    repositories {
      jcenter()
    }
    dependencies {
      classpath "io.ratpack:ratpack-gradle:1.4.5"
    }
}
 
apply plugin: "io.ratpack.ratpack-java"
repositories {
    jcenter()
}
dependencies {
    testCompile 'junit:junit:4.11'
    runtime "org.slf4j:slf4j-simple:1.7.21"
}
test {
    testLogging {
      events 'started', 'passed'
    }
}

3.2. アプリケーションの構築

ビルド管理を構成したら、組み込みの Netty サーバーを起動するクラスを作成し、デフォルトのリクエストを処理するための単純なコンテキストをビルドする必要があります。

public class Application {
	
    public static void main(String[] args) throws Exception {
        RatpackServer.start(server -> server.handlers(chain -> chain
          .get(ctx -> ctx.render("Welcome to Baeldung ratpack!!!"))));
    }
}

ご覧のとおり、 RatpackServer を使用して、サーバーを起動できます(デフォルトのポート5050)。 handlers()メソッドは、 Chain オブジェクトを受け取る関数を取ります。このオブジェクトは、それぞれの着信要求をすべてマップします。 この「ハンドラーチェーンAPI」は、応答処理戦略を構築するために使用されます。

このコードスニペットを実行し、ブラウザのhttp:// localhost:5050にアクセスすると、「Welcome toBaeldungratpack!!!」 表示されます。

同様に、HTTPPOSTリクエストをマッピングできます。

3.3. URLパスパラメータの処理

次の例では、アプリケーションでURLパスパラメータをキャプチャする必要があります。 Ratpackでは、PathTokensを使用してそれらをキャプチャします。

RatpackServer.start(server -> server
  .handlers(chain -> chain
  .get(":name", ctx -> ctx.render("Hello " 
  + ctx.getPathTokens().get("name") + " !!!"))));

ここでは、 nameURLパラメーターをマッピングしています。 http:// localhost:5050 / John のようなリクエストが来ると、応答は「HelloJohn!!!」になります。

3.4. フィルタあり/なしの要求/応答ヘッダーの変更

場合によっては、必要に応じてインラインHTTP応答ヘッダーを変更する必要があります。 Ratpackには、送信応答をカスタマイズするためのMutableHeadersがあります。

たとえば、応答の次のヘッダーを変更する必要があります: Access-Control-Allow-Origin Accept-Language 、および Accept-Charset

RatpackServer.start(server -> server.handlers(chain -> chain.all(ctx -> {
    MutableHeaders headers = ctx.getResponse().getHeaders();
    headers.set("Access-Control-Allow-Origin", "*");
    headers.set("Accept-Language", "en-us");
    headers.set("Accept-Charset", "UTF-8");
    ctx.next();
}).get(":name", ctx -> ctx
    .render("Hello " + ctx.getPathTokens().get("name") + "!!!"))));

MutableHeaders を使用して、3つのヘッダーを設定し、Chainにプッシュします。

同様に、着信リクエストヘッダーも確認できます。

ctx.getRequest().getHeaders().get("//TODO")

フィルタを作成することでも同じことができます。 Ratpackには、フィルターを作成するために実装できるハンドラーインターフェースがあります。 現在のContextをパラメーターとして受け取るメソッドhandle()、は1つだけです。

public class RequestValidatorFilter implements Handler {

    @Override
    public void handle(Context ctx) throws Exception {
        MutableHeaders headers = ctx.getResponse().getHeaders();
        headers.set("Access-Control-Allow-Origin", "*");
        ctx.next();
    }
}

このフィルターは次のように使用できます。

RatpackServer.start(
    server -> server.handlers(chain -> chain
      .all(new RequestValidatorFilter())
      .get(ctx -> ctx.render("Welcome to baeldung ratpack!!!"))));
}

3.5. JSONパーサー

Ratpackは、JSON解析にfaster-jacksonを内部的に使用します。 Jackson モジュールを使用して、任意のオブジェクトをJSONに解析できます。

解析に使用される単純なPOJOクラスを作成しましょう。

public class Employee {

    private Long id;
    private String title;
    private String name;

    // getters and setters 

}

ここでは、 Employee という名前の1つの単純なPOJOクラスを作成しました。このクラスには、 id、title 、およびnameの3つのパラメーターがあります。 次に、この Employee オブジェクトを使用してJSONに変換し、特定のURLがヒットしたときに同じものを返します。

List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee(1L, "Mr", "John Doe"));
employees.add(new Employee(2L, "Mr", "White Snow"));

RatpackServer.start(
    server -> server.handlers(chain -> chain
      .get("data/employees",
      ctx -> ctx.render(Jackson.json(employees)))));

ご覧のとおり、2つの Employee オブジェクトを手動でリストに追加し、Jacksonモジュールを使用してそれらをJSONとして解析しています。 / data / employees URLにアクセスするとすぐに、JSONオブジェクトが返されます。

ここで注意すべき点は、RatpackのJacksonモジュールがその場で必要な処理を行うため、ObjectMapperをまったく使用していないということです。

3.6. インメモリデータベース

Ratpackは、インメモリデータベースをファーストクラスでサポートしています。 JDBC接続プーリングにHikariCPを使用します。 これを使用するには、RatpackのHikariCPモジュールの依存関係pom.xmlに追加する必要があります。

<dependency>
    <groupId>io.ratpack</groupId>
    <artifactId>ratpack-hikari</artifactId>
    <version>1.4.5</version>
</dependency>

Gradle を使用している場合は、同じものをGradleビルドファイルに追加する必要があります。

compile ratpack.dependency('hikari')

次に、テーブルDDLステートメントを使用してSQLファイルを作成し、サーバーが稼働するとすぐにテーブルが作成されるようにする必要があります。 DDL.sqlファイルをsrc/ main / resources ディレクトリに作成し、それにいくつかのDDLステートメントを追加します。

H2データベースを使用しているため、その依存関係も追加する必要があります。

これで、HikariModuleを使用して、実行時にデータベースを初期化できます。

RatpackServer.start(
    server -> server.registry(Guice.registry(bindings -> 
      bindings.module(HikariModule.class, config -> {
          config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
          config.addDataSourceProperty("URL",
          "jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'classpath:/DDL.sql'");
      }))).handlers(...));

4. テスト

前述のように、RatpackはjUnitテストケースをファーストクラスでサポートしています。 MainClassApplicationUnderTest を使用すると、テストケースを簡単に作成し、エンドポイントをテストできます。

@RunWith(JUnit4.class)
public class ApplicationTest {

    MainClassApplicationUnderTest appUnderTest
      = new MainClassApplicationUnderTest(Application.class);

    @Test
    public void givenDefaultUrl_getStaticText() {
        assertEquals("Welcome to baeldung ratpack!!!", 
          appUnderTest.getHttpClient().getText("/"));
    }

    @Test
    public void givenDynamicUrl_getDynamicText() {
        assertEquals("Hello dummybot!!!", 
          appUnderTest.getHttpClient().getText("/dummybot"));
    }

    @Test
    public void givenUrl_getListOfEmployee() 
      throws JsonProcessingException {
 
        List<Employee> employees = new ArrayList<Employee>();
        ObjectMapper mapper = new ObjectMapper();
        employees.add(new Employee(1L, "Mr", "John Doe"));
        employees.add(new Employee(2L, "Mr", "White Snow"));

        assertEquals(mapper.writeValueAsString(employees), 
          appUnderTest.getHttpClient().getText("/data/employees"));
    }
 
    @After
    public void shutdown() {
        appUnderTest.close();
    }

}

close()メソッドを呼び出して、実行中の MainClassApplicationUnderTest インスタンスを手動で終了する必要があることに注意してください。これは、JVMリソースを不必要にブロックする可能性があるためです。 そのため、 @After アノテーションを使用して、テストケースが実行されたらインスタンスを強制的に終了しました。

5. 結論

この記事では、Ratpackの使用の簡単さを見てきました。

いつものように、完全なソースコードはGitHubから入手できます。