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に載っています]にあります。