1.概要
このチュートリアルでは、Kotlinプログラミング言語を使用してSpring WebFluxモジュールを使用する方法を説明します。
エンドポイントを定義する際に、アノテーションベースおよびラムダベースのスタイルアプローチを使用する方法を説明します。
2. Spring WebFluxとKotlin
Spring 5のリリースでは、2つの新しい大きな機能が導入されました。その中には、リアクティブプログラミングパラダイムのネイティブサポートとKotlinプログラミング言語を使用する可能性があります。
このチュートリアルを通して、私たちはすでに環境を設定し(この問題についてはhttps://www.baeldung.com/spring-boot-kotlin[このチュートリアルの1つ]を参照して)、Kotlin言語の構文(https:/)を理解していると仮定します。トピックに関する/www.baeldung.com/kotlin[その他のチュートリアル]。
3.アノテーションベースのアプローチ
WebFluxでは、
@ RequestMapping
や
@ PathVariable
などのSpringMVCフレームワークアノテーション、または
@ RestController
や
@ GetMapping
などの便利なアノテーションを使用して、着信要求を処理するエンドポイントを既知の方法で定義できます。
-
アノテーション名が同じであるという事実にもかかわらず、
WebFluxの
はメソッドを
非ブロック
にします。**
たとえば、このエンドポイントは次のとおりです。
@GetMapping(path =["/numbers"],
produces =[MediaType.APPLICATION__STREAM__JSON__VALUE])
@ResponseBody
fun getNumbers() = Flux.range(1, 100)
いくつかの最初の整数のストリームを生成します。サーバーが
localhost:8080
で実行されている場合は、次のコマンドでサーバーに接続します。
curl localhost:8080/stream
要求された番号を印刷します。
4.ラムダベースのアプローチ
エンドポイントを定義するためのより新しいアプローチは、バージョン1.8以降にJavaに存在するラムダ式によるものです。 Kotlinの助けを借りて、ラムダ式は以前のバージョンのJavaでも使用することができます。
WebFluxでは、ルーターの機能は
RequestPredicate
(つまり、誰がリクエストを管理すべきか)と
HandlerFunction
(つまり、リクエストの作り方)によって決定される機能です。
-
ハンドラ関数は
ServerRequest
インスタンスを受け取り、
Mono <ServerResponse>
を生成します。
Kotlinでは、
最後の関数引数がラムダ式である場合、それは括弧
の外側に置くことができます。
そのような構文によって、要求述語とハンドラ関数の間の分割を強調することができます。
router {
GET("/route") { __ -> ServerResponse.ok().body(fromObject(arrayOf(1, 2, 3))) }
}
ルーター機能用
この関数は、判読可能な形式になっています。GET型の要求が/routeに到着すると、HTTPステータスOKで、本文から構築された本文で応答を構築します(要求の内容を無視します。与えられたオブジェクト
さて、WebFluxでそれを機能させるためには、ルーター関数をクラスに入れるべきです:
@Configuration
class SimpleRoute {
@Bean
fun route() = router {
GET("/route") { __ -> ServerResponse.ok().body(fromObject(arrayOf(1, 2, 3))) }
}
}
多くの場合、私たちのアプリケーションのロジックは、より洗練されたルーター機能を構築する必要があります。
WebFluxでは、Kotlinのルーター関数DSLは
accept
、
and
、
or
、
nest
、
invoke
、
GET
、
POST
などのさまざまな関数を
extension functions
によって定義しています。
router {
accept(TEXT__HTML).nest {
(GET("/device/") or GET("/devices/")).invoke(handler::getAllDevices)
}
}
handler
変数は、標準の
HandlerFunction
シグネチャを持つメソッド
getAllDevices()
を実装するクラスのインスタンスである必要があります。
fun getAllDevices(request: ServerRequest): Mono<ServerResponse>
私達が上で述べたように。
関心事の適切な分離を維持するために、関連しないルータ機能の定義を別々のクラスに入れることができます。
@Configuration
class HomeSensorsRouters(private val handler: HomeSensorsHandler) {
@Bean
fun roomsRouter() = router {
(accept(TEXT__HTML) and "/room").nest {
GET("/light", handler::getLightReading)
POST("/light", handler::setLight)
}
}
//eventual other router function definitions
}
String
値のメソッド
pathVariable()
を使ってパス変数にアクセスできます。
val id = request.pathVariable("id")
一方、
ServerRequest
の本体へのアクセスは、
bodyToMono
および
bodyToFlux
メソッドによって実現されます。
val device: Mono<Device> = request
.bodyToMono(Device::class.java)
5.テスト
ルーターの機能をテストするために、テストしたいルーター
SimpleRoute()。route()
の
WebTestClient
インスタンスを作成する必要があります。
……
var client = WebTestClient.bindToRouterFunction(SimpleRoute()。route())。build()
……
これで、ルータのハンドラ関数がステータスOKを返すかどうかをテストする準備が整いました。
client.get()
.uri("/route")
.exchange()
.expectStatus()
.isOk
-
WebTestClientインターフェースは、サーバを実行しなくても
GET
、
POST
、
PUT
などのすべてのHTTPリクエストメソッドをテストできるようにするメソッドを定義します。 **
レスポンスボディの内容をテストするために、
json()
メソッドを使用することができます。
client.get()
.uri("/route")
.exchange()
.expectBody()
.json("[1, 2, 3]")
6.まとめ
この記事では、Kotlinを使用してWebFluxフレームワークの基本機能を使用する方法を説明しました。
エンドポイントを定義する際のよく知られたアノテーションベースのアプローチについて簡単に述べ、ラムダベースのスタイルアプローチでルーター機能を使用してそれらを定義する方法を説明するために時間をかけました。
すべてのコードスニペットは私達のリポジトリhttps://github.com/eugenp/tutorials/tree/master/spring-reactive-kotlin[GitHubに載っています]にあります。