Ratpack入門 (3) - hello world 詳解


Ratpack入門シリーズ

  1. Ratpack入門 (1) - Ratpackとは
  2. Ratpack入門 (2) - アーキテクチャー
  3. Ratpack入門 (3) - hello world 詳解
  4. Ratpack入門 (4) - ルーティング & 静的コンテンツ
  5. Ratpack入門 (5) - Json & Registry
  6. Ratpack入門 (6) - Promise
  7. Ratpack入門 (7) - Guice & Spring
  8. Ratpack入門 (8) - セッション
  9. Ratpack入門 (9) - Thymeleaf

hello world 詳解

ここでは、最初の記事のHello Worldサンプルをもう少し複雑にして、Ratpackという「水に慣れる」ことを目指します。

なおここでは型を明示するため、あえて冗長に書いています。石を投げないでください。

public final class Sample3_HelloWorldRevisited {


    public static void main( String[] args ) throws Exception {

        ServerConfig config = ServerConfig.builder()
                                          .port( 5050 )
                                          .connectTimeoutMillis( 10000 )
                                          .threads( 8 )
                                          .development( true )
                                          .build();

        Registry registry = Registry.empty();

        Action<Chain> handlers = ( Chain chain ) -> {

            Handler handler = ( Context ctx ) -> {
                ctx.render( "hello, world" );
            };

            chain.get( handler );
        };

        RatpackServer.of( spec -> spec.serverConfig( config )
                                      .registry( registry )
                                      .handlers( handlers ) )
                     .start();
    }

}

ServerConfig

サーバーの設定を変更するためのクラスです。ポート番号などがここから設定できます。

ServerConfigBuilderが用意されているのでこれを使うのが一番簡単だと思います。
json()yaml()等、ファイルから設定値を読み込むためのメソッドも用意されています。
他にもシステムプロパティーや引数などから設定するためのメソッドがあるので、好みの方法でServerConfigを作成できます。

development(boolean)

開発中モードを有効化するフラグです。
有効な場合、エラー発生時のハンドラーが自動的に追加されます。
※いまいちドキュメント化されていないので、他にも違いがあるのかもしれないです

実際に404エラーを発生させた場合の比較が、下記になります。
Ratpackの404エラーページ有無のほか、ログに独自ハンドラーを定義するよう警告されます。

development(true)

19:02:26.231 [ratpack-compute-1-2] ERROR ratpack.error.internal.DefaultDevelopmentErrorHandler - 404 client error for request to /hoge

development(false)

19:00:55.861 [ratpack-compute-1-4] WARN ratpack.error.internal.DefaultProductionErrorHandler - Default production error handler used to render client error, please add a ratpack.error.ClientErrorHandler instance to your application (method: GET, uri: /hoge)

development(true)は手軽に使えますが、本番環境では独自のErrorHandlerを作成することが推奨されているようです。

エラーハンドラーにはClientErrorHandlerServerErrorHandlerの二種類があります。

ClientErrorHandlerは404など、クライアントのリクエストに問題があった時に呼び出されます。
Contextintステータスコードを引数にとるerror()メソッドをオーバーライドします。

ServerErrorHandlerはハンドラーでエラーが発生したときに呼び出されます。
Contextと発生した例外を表すThrowableを引数にとるerror()メソッドがあります。
ServerErrorHandlerはRatpackにおけるエラー処理の最後の砦なので、基本的に例外を投げないことが推奨されています。

ところでこのメソッド、ExceptionではなくThrowableを引数に持っている通り、Errorが発生した場合も処理されます。
Javaでは一般的にErrorをキャッチしないことが推奨されていますので、その場合無理に復帰を試みないほうが良いと思われます。

Registry

Ratpackサーバーにモジュールなど部品を登録していくクラスです。今回は何も使わないので、空の実装を使用します。
上記のエラーハンドラーなどは、このレジストリに登録することで利用可能になります。

handlers

Ratpackは、Chainによってまとめられた複数のHandlerによってルーティングを行います。
Chain.get(String, Handler)メソッドは、HTTPのGETリクエストを、引数のハンドラーに結びつけています。
第一引数の文字列はパスです。今回のように省略するとルートにマッピングされます。

Context.render(Object)が、レスポンスのボディーを出力するメソッドです。
今回はStringを引数に渡しているので、そのままその文字列が出力されることになりますが、文字列以外のオブジェクトを渡すこともできます。
render()Registryに登録されたRendererが、型に応じて呼び出され、レスポンスに変換する仕組みになっています。
Stringには(正確にはCharSequenceには)組み込みのRendererがあるため、明示的にレンダラーを登録しなくても、Context.render()で呼び出せるという仕組みになっています。

RatpackServer.of( spec -> spec.serverConfig( config )
                              .registry( registry )
                              .handlers( handlers ) )
             .start();

of()メソッドでServerConfigRegistryHandlerを設定し、RatpackServerインスタンスを作成します。
start()メソッドでサーバーが起動され、リクエストの受け付けを開始します。

RatpackServerSpecの各メソッド(serverConfig()registry()handler()およびhandlers())は、対応するクラスのインスタンスを引数に持つものと、Action経由で設定するものなどいろいろあります。
個人的には例に挙げたように、コンフィグとレジストリに関してはインスタンスを、ハンドラーにはActionを使うのがやりやすい気がします。この辺は主観なのでいろいろ試してみることをお勧めします。