Spring WebClientフィルター

1. 概要

このチュートリアルでは、機能的でリアクティブなWebフレームワークであるlink:/spring-5-functional-web[_Spring WebFlux_]の_WebClient_フィルターを調べます。

2. リクエストフィルター

*フィルターは、クライアントの要求(または応答)をインターセプト、検査、および変更できます。*フィルターは、ロジックが1か所に留まるため、すべての要求に機能を追加するのに非常に適しています。 ユースケースには、クライアントリクエストの監視、変更、ログ記録、認証などがあります。
*リクエストには、ゼロ個以上のフィルターの順序付きチェーンがあります。*
Spring Reactiveでは、フィルターは機能インターフェイス_ExchangeFilterFunction_のインスタンスです。 フィルター関数には、変更する_ClientRequest_と次の_ExchangeFilterFunction_の2つのパラメーターがあります。
通常、フィルター関数は、フィルターチェーン内の次の関数を呼び出して戻ります。
ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
    LOG.info("WebClient fitler executed");
    return nextFilter.exchange(clientRequest);
};

3. _WebClient_フィルタリング

要求フィルターを実装した後、_WebClient_インスタンスに「アタッチ」する必要があります。 これは、_WebClient_の作成中にのみ実行できます。
それでは、_WebClient_の作成方法を見てみましょう。 最初のオプションは、ベースURLの有無にかかわらず_WebClient.create()_を呼び出すことです。
WebClient webClient = WebClient.create();
残念ながら、これではフィルターを追加できません。 2番目のオプションは、探しているものです。
  • _WebClient.builder()_を使用することで、フィルターを追加できます*:

WebClient webClient = WebClient.builder()
  .filter(filterFunction)
  .build();

4. カスタムフィルター

クライアントから送信されたHTTP GETリクエストをカウントするフィルターから始めましょう。
フィルターは要求メソッドを調べ、GET要求の場合に「グローバル」カウンターを増やします。
ExchangeFilterFunction countingFunction = (clientRequest, nextFilter) -> {
    HttpMethod httpMethod = clientRequest.method();
    if (httpMethod == HttpMethod.GET) {
        getCounter.incrementAndGet();
    }
    return nextFilter.exchange(clientRequest);
};
定義する2番目のフィルターは、リクエストURLパスにバージョン番号を追加します。 _ClientRequest.from()_メソッドを利用して、現在のリクエストオブジェクトから新しいリクエストオブジェクトを作成し、変更されたURLを設定します。
その後、新しい変更された要求オブジェクトを使用してフィルターチェーンの実行を続けます。
ExchangeFilterFunction urlModifyingFilter = (clientRequest, nextFilter) -> {
    String oldUrl = clientRequest.url().toString();
    URI newUrl = URI.create(oldUrl + "/" + version);
    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
      .url(newUrl)
      .build();
    return nextFilter.exchange(filteredRequest);
};
次に、送信されたリクエストのメソッドとそのURLを記録するフィルターを定義しましょう。 これらの詳細は、リクエストオブジェクトで利用できます。
あとは、出力ストリームに出力するだけです。
ExchangeFilterFunction loggingFilter = (clientRequest, nextFilter) -> {
    printStream.print("Sending request " + clientRequest.method() + " " + clientRequest.url());
    return nextFilter.exchange(clientRequest);
};

5. 標準フィルター

最後に、*基本認証*を見てみましょう。これは、要求フィルタリングの非常に一般的な使用例です。
ヘルパークラス_ExchangeFilterFunctions_は、_authorization_ヘッダーをリクエストに追加する処理を行う_basicAuthentication()_フィルター関数を提供します。
そのため、フィルターを定義する必要はありません。
WebClient webClient = WebClient.builder()
  .filter(ExchangeFilterFunctions.basicAuthentication(user, password))
  .build();

6. 結論

この短い記事では、SpringでのWebFluxクライアントのフィルタリングについて説明しました。
いつものように、コード例はhttps://github.com/eugenp/tutorials/tree/master/spring-5-reactive-2[GitHubで]にあります。