WebFluxとKotlinでReactive Web

この記事は 『CRESCO Advent Calendar 2017』 10日目の記事です。

VPA関連を書こうと思ったけれど、他の人と被りまくりそうな気がするので回避。

「ねえGoogle、WebFluxでAPIを実装してみて」
「Alexa、KotlinでAPIを実装してみて」

Spring 5.0のリリースで、WebFluxやKotlinのサポートが追加されました。
Spring WebFluxは、リアクティブプログラミングが出来る新しいフレームワークです。
Spring MVCはServlet APIベースでしたが、Spring WebFluxはReactive Streamベースの新しいHTTP API上に実装されています。

https://spring.io/

Kotlinは、Android開発言語として正式採用されたJVM言語です。
今日はKotlinを使ってSpring WebFluxでリアクティブなWeb APIでも作ってみようかと思います。

環境

OS: macOS Sierra Version 10.12.6
Java: 1.8.0_151
Gradle: 4.2
Spring Boot: 2.0.0 M6
Kotlin: 1.1.51

プロジェクト作成

プロジェクトは Spring Initializr を使ってサクッと作ります。

Gradle projectにして、言語は Kotlinに。Spring Boot は 2.0.0 M6 を選択。
Spring Boot は 2.0 から Spring5 に対応していますが、11月20日の執筆時点ではまだM6(pre)です。
Dependencies はとりあえず、Reactive Web を選んでおけばWebFluxが使えます。

build.gradle はこんな感じになります。

Web API 作成

Annotation-based Programming Model と Functional Programming Model

Spring WebFlux はアノテーションベースのプログラミングモデルと、ファンクショナルなプログラミングモデルの2パターンが用意されています。

https://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html

前者は @RestController とか @GetMapping といった Spring MVCでおなじみのアノテーションを使って実装します。
後者は、ラムダベースの新しい実装方法になります。
今回は、後者の方で作ってみます。

RouterFunctions

リクエスト要求はRouter Function によって Handler Function にルーティングされます。
@Controllerクラスの@RequestMappingアノテーションのような感じですかね。

HandlerFunctions

Handler Functionはこんな感じ。
普通にJsonでレスポンス返すやつと、Stream感のあるレスポンスを返すやつを作ってみます。
FluxはReactive StreamのPublisherを実装したクラスでN要素のストリームを実現してます。
対してMonoは1 or 0要素のPublisherです。

以上でAPIの作成は終わり。とりあえず、今回はGETだけです。

API実行

それでは実行してみます。

おお、いつものtomcatではなく Nettyが起動してますね。
curlでAPIを叩いて確認してみます。まずは、普通にJSON返すやつを。

普通にJSON Array返してます。
続いて、Stream感のあるやつ。

わかりずらいですが、1秒おきに1件ずつ返してます。

以上、ざっと触ってみました。
今回のサンプルコードは、ココ

最後に

今回は、Spring WebFlux を使って簡単なAPIを作ってみました。Reactor対応のHTTP Client とかも試してみたいですね。
Kotlinについては記事の中では全く触れてないですが、いいですね。
KotlinのテスティングフレームワークSpekも良さそうな感じ。

最後にSpring Bootのスプラッシュをクリスマスっぽくして、

それでは、また。