Spring WebFlux を Router Functions と Kotlin で書く

会社では Spring Framework と Java8 を使ってサービスを書いていますが、趣味としては最新の Spring Framework 5 を Spring Boot 2 から使ってみることにしました。
その中でノンブロッキング処理の利用に関して、 C# での Reactive Extensions でなじみがあったような構文を見つけたので、これまた新しく出てきた WebFlux と Router Functions も一緒に Kotlin で書いてみました。 WebFlux は、 Reactor と呼ばれるオブサーバパターンを使った Push 型コレクションを利用したリクエストの仕組みです。今まで通り Controller を使うこともできます。

プロジェクト全体のソースコードはこちらから。ちょっとだけ Kotlin で DSL を加えています。

まず、 “Spring Initializr” で Kotlin 、 Spring Boot 2.0.0 M4 を選び、 Dependency には Reactive Web ( WebFlux ) を追加します。
続いて、いつも通りに @SpringBootApplication を使って起動用クラスを作ります。 Controller を使う今までからあった方法とはちょっと変わり、そのクラスの中に Bean routes:RouterFunction<ServerResponse>定義しています。ここで Router をそのまま返したり、 Router 同士を繋げて返すなどし、ルーティングの設定を行います。(ちなみに Router インターフェースは公式にはなく、自分で定義しています。参考記事でもそうなっていません。こうした理由としては、私は Router が増えたときに引数を増やすのが面倒に感じたからです。)

ハンドラ( FooHandlerBarHandler )については、 router という Kotlin DSL をデフォルトで利用することもできます。 Kotlin サポートもしっかりしているようで楽しく書いていけそうですね。
他には特筆することはないですが、関数を渡すのではなくラムダ内で実行させるほうが短く書けてしまうのはちょっと複雑な気持ちになります。

最後に単体テストです。 WebFlux においては WebTestClient を利用するのが王道のようです。 lateinit を駆使して事前処理を書きますval にできないのがちょっと気がかり。
Security などを使った場合はテストのパラメタの指定がもっと複雑なようですが、このサンプルはシンプルな構造なので、比較的楽だと思われます。

ちょこちょこ自作 DSL を入れていますが、この辺はもうちょっとライブラリ側(と Kotlin の型システム)に改善の余地がありそうですね。

参照記事