4.0.9

このプロジェクトは、Spring 6、Spring Boot 3、プロジェクト Reactor などの Spring エコシステム上に構築された API ゲートウェイを提供します。Spring Cloud Gateway は、API にルーティングするためのシンプルでありながら効果的な方法を提供し、セキュリティ、監視 / メトリクス、復元力などの横断的関心事を提供することを目的としています。

1. Spring Cloud Gateway を含める方法

プロジェクトに Spring Cloud Gateway を含めるには、グループ ID が org.springframework.cloud でアーティファクト ID が spring-cloud-starter-gateway のスターターを使用します。現在の Spring Cloud リリーストレインを使用したビルドシステムのセットアップの詳細については、Spring Cloud プロジェクトページを参照してください。

スターターを含めても、ゲートウェイを有効にしたくない場合は、spring.cloud.gateway.enabled=false を設定します。

Spring Cloud Gateway は Spring BootSpring WebFluxプロジェクト Reactor (英語) に基づいて構築されています。その結果、使い慣れた同期ライブラリ (Spring Data や Spring Security など) の多くと、よく知っているパターンは、Spring Cloud Gateway を使用する場合には適用されない可能性があります。これらのプロジェクトの 未知 である場合は、Spring Cloud Gateway を使用する前に、それらのドキュメントを読んでいくつかの新しい概念を理解することから始めることをお勧めします。
Spring Cloud Gateway には、Spring Boot および Spring Webflux によって提供される Netty ランタイムが必要です。従来のサーブレットコンテナーで、または WAR としてビルドされた場合は機能しません。

2. 用語集

  • ルート : ゲートウェイの基本的な構成要素。これは、ID、宛先 URI、述語のコレクション、フィルターのコレクションによって定義されます。集約述語が true の場合、ルートは一致します。

  • 述語 : これは Java 8 関数の述語 (標準 Javadoc) です。入力型は Spring Framework ServerWebExchange (Javadoc) です。これにより、ヘッダーやパラメーターなど、HTTP リクエストのすべてに一致させることができます。

  • フィルター : これらは、特定のファクトリで構築された GatewayFilter [GitHub] (英語) のインスタンスです。ここでは、ダウンストリームリクエストを送信する前または後にリクエストとレスポンスを変更できます。

3. 使い方

次の図は、Spring Cloud Gateway がどのように機能するかについての概要を示しています。

Spring Cloud Gateway Diagram

クライアントは Spring Cloud Gateway にリクエストを送信します。ゲートウェイハンドラーマッピングがリクエストがルートに一致すると判断した場合、そのリクエストはゲートウェイ Web ハンドラーに送信されます。このハンドラーは、リクエストに固有のフィルターチェーンを介してリクエストを実行します。フィルターが点線で分割されている理由は、プロキシリクエストが送信される前と後の両方でフィルターがロジックを実行できるためです。すべての「事前」フィルターロジックが実行されます。次に、プロキシリクエストが行われます。プロキシリクエストが行われた後、「ポスト」フィルターロジックが実行されます。

ポートのないルートで定義された URI は、HTTP URI と HTTP SURI のそれぞれに対して 80 および 443 のデフォルトのポート値を取得します。

4. ルート述語ファクトリとゲートウェイフィルターファクトリの設定

述語とフィルターを構成するには、ショートカットと完全に展開された引数の 2 つの方法があります。以下のほとんどの例では、ショートカットを使用しています。

名前と引数の名前は、各セクションの最初または 2 つの文に code としてリストされています。引数は通常、ショートカット構成に必要な順序でリストされています。

4.1. ショートカット構成

ショートカット構成は、フィルター名、等号(=)、コンマで区切られた引数値(,)で認識されます。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

前のサンプルでは、2 つの引数、Cookie 名 mycookie と mycookievalue に一致する値を使用して Cookie ルート述語ファクトリを定義しています。

4.2. 完全に展開された引数

完全に展開された引数は、名前と値のペアを持つ標準の yaml 構成のように見えます。通常、name キーと args キーがあります。args キーは、述語またはフィルターを構成するためのキーと値のペアのマップです。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

これは、上記の Cookie 述語のショートカット構成の完全な構成です。

5. ルート述語ファクトリ

Spring Cloud Gateway は、Spring WebFlux HandlerMapping インフラストラクチャーの一部としてルートと一致します。Spring Cloud Gateway には、多くの組み込みルート述語ファクトリが含まれています。これらの述語はすべて、HTTP リクエストのさまざまな属性で一致します。複数のルート述語ファクトリを論理 and ステートメントと組み合わせることができます。

5.1. アフタールート述語ファクトリ

After ルート述語ファクトリは、1 つのパラメーター datetime (java ZonedDateTime)を取ります。この述語は、指定された日時以降に発生するリクエストと一致します。次の例では、アフタールート述語を設定します。

例 1: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

このルートは、2017 年 1 月 20 日 17:42 山岳部標準時(デンバー)以降に行われたすべてのリクエストに一致します。

5.2. ビフォアルート述語ファクトリ

Before ルート述語ファクトリは、1 つのパラメーター datetime (java ZonedDateTime)を取ります。この述語は、指定された datetime の前に発生するリクエストと一致します。次の例では、beforeroute 述語を設定します。

例 2: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

このルートは、2017 年 1 月 20 日 17:42 山岳部標準時(デンバー)より前に行われたすべてのリクエストに一致します。

5.3. ルート間述語ファクトリ

Between ルート述語ファクトリは、java ZonedDateTime オブジェクトである datetime1 と datetime2 の 2 つのパラメーターを取ります。この述語は、datetime1 の後および datetime2 の前に発生するリクエストと一致します。datetime2 パラメーターは datetime1 の後になければなりません。次の例では、ルート間述語を設定します。

例 3: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

このルートは、2017 年 1 月 20 日 17:42 山岳部標準時(デンバー)以降および 2017 年 1 月 21 日 17:42 山岳部標準時(デンバー)より前に行われたすべてのリクエストに一致します。これは、メンテナンスウィンドウに役立つ可能性があります。

Cookie ルート述語ファクトリは、Cookie name と regexp (Java 正規表現)の 2 つのパラメーターを取ります。この述語は、指定された名前を持ち、値が正規表現と一致する Cookie と一致します。次の例では、Cookie ルート述語ファクトリを設定します。

例 4: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

このルートは、値が ch.p 正規表現と一致する chocolate という名前の Cookie を持つリクエストに一致します。

5.5. ヘッダールート述語ファクトリ

Header ルート述語ファクトリは、header と regexp (Java 正規表現)の 2 つのパラメーターを取ります。この述語は、値が正規表現と一致する名前を持つヘッダーと一致します。次の例では、ヘッダールート述語を構成します。

例 5: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

このルートは、リクエストに X-Request-Id という名前のヘッダーがあり、その値が \d+ 正規表現と一致する場合(つまり、1 桁以上の値を持つ場合)に一致します。

5.6. ホストルート述語ファクトリ

Host ルート述語ファクトリは 1 つのパラメーターを取ります: ホスト名 patterns のリスト。パターンは、. をセパレーターとする Ant スタイルのパターンです。この述語は、パターンに一致する Host ヘッダーに一致します。次の例では、ホストルート述語を設定します。

例 6: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

URI テンプレート変数({sub}.myhost.org など)もサポートされています。

このルートは、リクエストに www.somehost.orgbeta.somehost.orgwww.anotherhost.org の値を持つ Host ヘッダーがある場合に一致します。

この述語は、URI テンプレート変数(前の例で定義された sub など)を名前と値のマップとして抽出し、ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE で定義されたキーを使用して ServerWebExchange.getAttributes() に配置します。これらの値は、GatewayFilter ファクトリで使用できるようになります。

5.7. メソッドルート述語ファクトリ

Method ルート述語ファクトリは 1 つ以上のパラメーターである methods 引数を取ります: 一致する HTTP メソッド。次の例では、メソッドルート述語を設定します。

例 7: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

このルートは、リクエストメソッドが GET または POST の場合に一致します。

5.8. パスルート述語ファクトリ

Path ルート述語ファクトリは、Spring PathMatcher patterns のリストと matchTrailingSlash と呼ばれるオプションのフラグ(デフォルトは true)の 2 つのパラメーターを取ります。次の例では、パスルート述語を設定します。

例 8: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

このルートは、リクエストパスが /red/1 または /red/1/ または /red/blue または /blue/green の場合に一致します。

matchTrailingSlash が false に設定されている場合、リクエストパス /red/1/ は一致しません。

この述語は、URI テンプレート変数(前の例で定義された segment など)を名前と値のマップとして抽出し、ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE で定義されたキーを使用して ServerWebExchange.getAttributes() に配置します。これらの値は、GatewayFilter ファクトリで使用できるようになります。

これらの変数へのアクセスを容易にするために、ユーティリティメソッド(get と呼ばれる)を使用できます。次の例は、get メソッドの使用方法を示しています。

Map<String, String> uriVariables = ServerWebExchangeUtils.getUriTemplateVariables(exchange);

String segment = uriVariables.get("segment");

5.9. クエリルート述語ファクトリ

Query ルート述語ファクトリは、必須の param とオプションの regexp (Java 正規表現)の 2 つのパラメーターを取ります。次の例では、クエリルート述語を設定します。

例 9: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=green

リクエストに green クエリパラメーターが含まれている場合、上記のルートは一致します。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: https://example.org
        predicates:
        - Query=red, gree.

上記のルートは、リクエストに gree. 正規表現と値が一致する red クエリパラメーターが含まれている場合に一致するため、green と greet が一致します。

5.10. RemoteAddr ルート述語ファクトリ

RemoteAddr ルート述語ファクトリは sources のリスト(最小サイズ 1)を取得します。これは、192.168.0.1/16 (192.168.0.1 は IP アドレス、16 はサブネットマスク)などの CIDR 表記(IPv4 または IPv6)文字列です。次の例では、RemoteAddr ルート述語を構成します。

例 10: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

このルートは、リクエストのリモートアドレスがたとえば 192.168.1.10 であった場合に一致します。

5.10.1. リモートアドレスの解決方法の変更

デフォルトでは、RemoteAddr ルート述語ファクトリは受信リクエストからのリモートアドレスを使用します。Spring Cloud Gateway がプロキシ層の背後にある場合、これは実際のクライアント IP アドレスと一致しない可能性があります。

カスタム RemoteAddressResolver を設定することにより、リモートアドレスを解決する方法をカスタマイズできます。Spring Cloud Gateway には、X-Forwarded-For ヘッダー [Mozilla] XForwardedRemoteAddressResolver に基づくデフォルト以外のリモートアドレスリゾルバーが 1 つ付属しています。

XForwardedRemoteAddressResolver には 2 つの静的コンストラクターメソッドがあり、セキュリティに対して異なるアプローチを取ります。

  • XForwardedRemoteAddressResolver::trustAll は、X-Forwarded-For ヘッダーで見つかった最初の IP アドレスを常に取得する RemoteAddressResolver を返します。このアプローチは、悪意のあるクライアントが X-Forwarded-For の初期値を設定する可能性があるため、スプーフィングに対して脆弱です。これは、リゾルバーによって受け入れられます。

  • XForwardedRemoteAddressResolver::maxTrustedIndex は、Spring Cloud Gateway の前で実行されている信頼できるインフラストラクチャの数に相関するインデックスを取ります。たとえば、Spring Cloud Gateway が HAProxy を介してのみアクセス可能である場合は、値 1 を使用する必要があります。Spring Cloud Gateway にアクセスする前に信頼できるインフラストラクチャの 2 ホップが必要な場合は、値 2 を使用する必要があります。

次のヘッダー値を検討してください。

X-Forwarded-For: 0.0.0.1, 0.0.0.2, 0.0.0.3

次の maxTrustedIndex 値は、次のリモートアドレスを生成します。

maxTrustedIndex 結果

[Integer.MIN_VALUE,0]

(無効、初期化中の IllegalArgumentException

1

0.0.0.3

2

0.0.0.2

3

0.0.0.1

[4, Integer.MAX_VALUE]

0.0.0.1

次の例は、Java で同じ構成を実現する方法を示しています。

例 11: GatewayConfig.java
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)

5.11. ウェイトルート述語ファクトリ

Weight ルート述語ファクトリは、group と weight (int)の 2 つの引数を取ります。重みはグループごとに計算されます。次の例では、重みルート述語を構成します。

例 12: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

このルートは、トラフィックの最大 80% を weighthigh.org (英語) に転送し、トラフィックの最大 20% を weighlow.org (英語) に転送します。

5.12. XForwarded リモート Addr ルート述語ファクトリ

XForwarded Remote Addr ルート述語ファクトリは sources のリスト(最小サイズ 1)を取得します。これは、192.168.0.1/16 (192.168.0.1 は IP アドレス、16 はサブネットマスク)などの CIDR 表記(IPv4 または IPv6)文字列です。

このルート述語を使用すると、X-Forwarded-For HTTP ヘッダーに基づいてリクエストをフィルターに掛けることができます。

これは、ロードバランサーや Web アプリケーションファイアウォールなどのリバースプロキシで使用できます。この場合、リクエストは、これらのリバースプロキシで使用される IP アドレスの信頼できるリストからのものである場合にのみ許可されます。

次の例では、XForwardedRemoteAddr ルート述語を構成します。

例 13: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: xforwarded_remoteaddr_route
        uri: https://example.org
        predicates:
        - XForwardedRemoteAddr=192.168.1.1/24

このルートは、X-Forwarded-For ヘッダーに 192.168.1.10 などが含まれている場合に一致します。

6. GatewayFilter ファクトリ

ルートフィルターを使用すると、受信 HTTP リクエストまたは発信 HTTP レスポンスを何らかの方法で変更できます。ルートフィルターは特定のルートにスコープされます。Spring Cloud Gateway には、多くの GatewayFilter ファクトリが組み込まれています。

次のフィルターの使用方法の詳細な例については、単体テスト [GitHub] (英語) を参照してください。

6.1. AddRequestHeader GatewayFilter ファクトリ

AddRequestHeader GatewayFilter ファクトリは、name および value パラメーターを取ります。次の例では、AddRequestHeader GatewayFilter を構成します。

例 14: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue

このリストは、一致するすべてのリクエストのダウンストリームリクエストのヘッダーに X-Request-red:blue ヘッダーを追加します。

AddRequestHeader は、パスまたはホストの照合に使用される URI 変数を認識しています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する AddRequestHeader GatewayFilter を構成します。

例 15: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeader=X-Request-Red, Blue-{segment}

6.2. AddRequestHeadersIfNotPresent GatewayFilter ファクトリ

AddRequestHeadersIfNotPresent GatewayFilter ファクトリは、コロンで区切られた name と value のペアのコレクションを取ります。次の例では、AddRequestHeadersIfNotPresent GatewayFilter を構成します。

例 16: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_headers_route
        uri: https://example.org
        filters:
        - AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green

このリストは、一致するすべてのリクエストのダウンストリームリクエストのヘッダーに X-Request-Color-1:blue と X-Request-Color-2:green の 2 つのヘッダーを追加します。これは AddRequestHeader の動作と似ていますが、AddRequestHeader とは異なり、ヘッダーがまだ存在しない場合にのみ実行されます。それ以外の場合は、クライアントリクエストの元の値が送信されます。

さらに、多値ヘッダーを設定するには、AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green のようにヘッダー名を複数回使用します。

AddRequestHeadersIfNotPresent は、パスまたはホストの照合に使用される URI 変数もサポートしています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する AddRequestHeadersIfNotPresent GatewayFilter を構成します。

例 17: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}

6.3. AddRequestParameter GatewayFilter ファクトリ

AddRequestParameter GatewayFilter ファクトリは、name および value パラメーターを取ります。次の例では、AddRequestParameter GatewayFilter を構成します。

例 18: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=red, blue

これにより、一致するすべてのリクエストのダウンストリームリクエストのクエリ文字列に red=blue が追加されます。

AddRequestParameter は、パスまたはホストの照合に使用される URI 変数を認識しています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する AddRequestParameter GatewayFilter を構成します。

例 19: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddRequestParameter=foo, bar-{segment}

6.4. AddResponseHeader GatewayFilter ファクトリ

AddResponseHeader GatewayFilter ファクトリは、name および value パラメーターを取ります。次の例では、AddResponseHeader GatewayFilter を構成します。

例 20: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Red, Blue

これにより、一致するすべてのリクエストのダウンストリームレスポンスのヘッダーに X-Response-Red:Blue ヘッダーが追加されます。

AddResponseHeader は、パスまたはホストの照合に使用される URI 変数を認識しています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する AddResponseHeader GatewayFilter を構成します。

例 21: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - AddResponseHeader=foo, bar-{segment}

6.5. CircuitBreaker GatewayFilter ファクトリ

Spring Cloud CircuitBreaker GatewayFilter ファクトリは、Spring Cloud CircuitBreaker API を使用して、ゲートウェイルートをサーキットブレーカーにラップします。Spring Cloud CircuitBreaker は、Spring Cloud Gateway で使用できる複数のライブラリをサポートします。Spring Cloud は、そのまま Resilience4J をサポートします。

Spring Cloud CircuitBreaker フィルターを有効にするには、クラスパスに spring-cloud-starter-circuitbreaker-reactor-resilience4j を配置する必要があります。次の例では、Spring Cloud CircuitBreaker GatewayFilter を構成します。

例 22: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: https://example.org
        filters:
        - CircuitBreaker=myCircuitBreaker

サーキットブレーカーを構成するには、使用している基礎となるサーキットブレーカーの実装の構成を参照してください。

Spring Cloud CircuitBreaker フィルターは、オプションの fallbackUri パラメーターを受け入れることもできます。現在、forward: スキーム化 URI のみがサポートされています。フォールバックが呼び出されると、リクエストは URI と一致するコントローラーに転送されます。次の例では、このようなフォールバックを構成します。

例 23: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
        - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

次のリストは、Java でも同じことを行います。

例 24: Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

この例では、サーキットブレーカーのフォールバックが呼び出されたときに /inCaseofFailureUseThis URI に転送します。この例は、(オプションの)Spring Cloud LoadBalancer ロードバランシング(宛先 URI の lb プレフィックスによって定義される)も示していることに注意してください。

CircuitBreaker は fallbackUri の URI 変数もサポートします。これにより、元のホストの転送セクションや PathPattern 式 (Javadoc) を使用した URL パスなど、より複雑なルーティングオプションが可能になります。

以下の例では、呼び出し consumingServiceEndpoint/users/1 が inCaseOfFailureUseThis/users/1 にリダイレクトされます。

例 25: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint/{*segments}
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis/{segments}

主なシナリオは、fallbackUri を使用して、ゲートウェイアプリケーション内の内部コントローラーまたはハンドラーを定義することです。ただし、次のように、リクエストを外部アプリケーションのコントローラーまたはハンドラーに再ルーティングすることもできます。

例 26: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

この例では、ゲートウェイアプリケーションに fallback エンドポイントまたはハンドラーはありません。ただし、localhost:9994 で登録されている別のアプリケーションに 1 つあります。

リクエストがフォールバックに転送される場合、Spring Cloud CircuitBreaker ゲートウェイフィルターは、それを引き起こした Throwable も提供します。これは、ゲートウェイアプリケーション内でフォールバックを処理するときに使用できる ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性として ServerWebExchange に追加されます。

外部コントローラー / ハンドラーのシナリオでは、例外の詳細とともにヘッダーを追加できます。これを行う方法の詳細については、FallbackHeaders GatewayFilter ファクトリセクションを参照してください。

6.5.1. ステータスコードでサーキットブレーカーをトリップする

場合によっては、ラップするルートから返されたステータスコードに基づいてサーキットブレーカーを作動させたい場合があります。サーキットブレーカーの構成オブジェクトは、返された場合にサーキットブレーカーが作動する状態コードのリストを取得します。サーキットブレーカーを作動させたいステータスコードを設定するときは、ステータスコード値で整数を使用するか、HttpStatus 列挙型の文字列表現を使用できます。

例 27: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: circuitbreaker_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingServiceEndpoint
        filters:
        - name: CircuitBreaker
          args:
            name: myCircuitBreaker
            fallbackUri: forward:/inCaseOfFailureUseThis
            statusCodes:
              - 500
              - "NOT_FOUND"
例 28: Application.java
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint")
            .filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR"))
                .rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088")
        .build();
}

6.6. CacheRequestBody GatewayFilter ファクトリ

状況によっては、リクエスト本文を読み取る必要があります。リクエストは一度しか読み取れないため、リクエストボディをキャッシュする必要があります。CacheRequestBody フィルターを使用して、リクエスト本文をキャッシュしてからダウンストリームに送信し、exchange 属性から本文を取得できます。

次のリストは、リクエスト本文 GatewayFilter をキャッシュする方法を示しています。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("cache_request_body_route", r -> r.path("/downstream/**")
            .filters(f -> f.prefixPath("/httpbin")
                .cacheRequestBody(String.class).uri(uri))
        .build();
}
例 29: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: cache_request_body_route
        uri: lb://downstream
        predicates:
        - Path=/downstream/**
        filters:
        - name: CacheRequestBody
          args:
            bodyClass: java.lang.String

CacheRequestBody はリクエスト本文を抽出し、本文クラス (前の例で定義された java.lang.String など) に変換します。次に、CacheRequestBody は、ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR で定義されたキーを使用して、ServerWebExchange.getAttributes() から使用可能な属性にそれを配置します。

このフィルターは、HTTP (HTTPS を含む) リクエストでのみ機能します。

6.7. DedupeResponseHeader GatewayFilter ファクトリ

DedupeResponseHeader GatewayFilter ファクトリは、name パラメーターとオプションの strategy パラメーターを取ります。name には、スペースで区切られたヘッダー名のリストを含めることができます。次の例では、DedupeResponseHeader GatewayFilter を構成します。

例 30: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: dedupe_response_header_route
        uri: https://example.org
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

これにより、ゲートウェイ CORS ロジックとダウンストリームロジックの両方が追加した場合に、Access-Control-Allow-Credentials および Access-Control-Allow-Origin レスポンスヘッダーの重複値が削除されます。

DedupeResponseHeader フィルターは、オプションの strategy パラメーターも受け入れます。受け入れられる値は、RETAIN_FIRST (デフォルト)、RETAIN_LASTRETAIN_UNIQUE です。

6.8. FallbackHeaders GatewayFilter ファクトリ

FallbackHeaders ファクトリでは、次のシナリオのように、外部アプリケーションの fallbackUri に転送されるリクエストのヘッダーに Spring Cloud CircuitBreaker 実行例外の詳細を追加できます。

例 31: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: CircuitBreaker
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback
        filters:
        - name: FallbackHeaders
          args:
            executionExceptionTypeHeaderName: Test-Header

この例では、サーキットブレーカーの実行中に実行例外が発生した後、リクエストは localhost:9994 で実行されているアプリケーションの fallback エンドポイントまたはハンドラーに転送されます。例外型、メッセージ、(利用可能な場合)根本原因の例外型とメッセージを含むヘッダーは、FallbackHeaders フィルターによってそのリクエストに追加されます。

次の引数の値を設定することにより、構成内のヘッダーの名前を上書きできます(デフォルト値で示されています)。

  • executionExceptionTypeHeaderName ("Execution-Exception-Type")

  • executionExceptionMessageHeaderName ("Execution-Exception-Message")

  • rootCauseExceptionTypeHeaderName ("Root-Cause-Exception-Type")

  • rootCauseExceptionMessageHeaderName ("Root-Cause-Exception-Message")

サーキットブレーカーとゲートウェイの詳細については、Spring Cloud CircuitBreaker ファクトリセクションを参照してください。

6.9. JsonToGrpc GatewayFilter ファクトリ

JSONToGRPCFilter GatewayFilter Factory は、JSON ペイロードを gRPC リクエストに変換します。

フィルターは次の引数を取ります。

  • protoDescriptor: プロト記述子ファイル。

このファイルは、protoc を使用し、--descriptor_set_out フラグを指定して生成できます。

protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb  \
src/main/resources/proto/hello.proto
  • protoFile: プロト定義ファイル。

  • service: リクエストを処理するサービスの短い名前。

  • method: リクエストを処理するサービスのメソッド名。

streaming はサポートされていません。

application.yml.

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("json-grpc", r -> r.path("/json/hello").filters(f -> {
                String protoDescriptor = "file:src/main/proto/hello.pb";
                String protoFile = "file:src/main/proto/hello.proto";
                String service = "HelloService";
                String method = "hello";
                return f.jsonToGRPC(protoDescriptor, protoFile, service, method);
            }).uri(uri))
spring:
  cloud:
    gateway:
      routes:
        - id: json-grpc
          uri: https://localhost:6565/testhello
          predicates:
            - Path=/json/**
          filters:
            - name: JsonToGrpc
              args:
                protoDescriptor: file:proto/hello.pb
                protoFile: file:proto/hello.proto
                service: HelloService
                method: hello

ゲートウェイを介して /json/hello へのリクエストが行われると、リクエストは hello.proto で提供される定義を使用して変換され、HelloService/hello に送信され、返されるレスポンスは JSON に変換されます。

デフォルトでは、デフォルトの TrustManagerFactory を使用して NettyChannel を作成します。ただし、型 GrpcSslConfigurer の Bean を作成することにより、この TrustManager をカスタマイズできます。

@Configuration
public class GRPCLocalConfiguration {
    @Bean
    public GRPCSSLContext sslContext() {
        TrustManager trustManager = trustAllCerts();
        return new GRPCSSLContext(trustManager);
    }
}

6.10. LocalResponseCache GatewayFilter ファクトリ

このフィルターを使用すると、レスポンスの本文とヘッダーをキャッシュして、次の規則に従うことができます。

  • 本文のない GET リクエストのみをキャッシュできます。

  • HTTP 200 (OK)、HTTP 206 (部分的なコンテンツ)、または HTTP 301 (完全削除) のいずれかのステータスコードのレスポンスのみをキャッシュします。

  • Cache-Control ヘッダーで許可されていない場合 (リクエストに no-store が存在するか、レスポンスに no-store または private が存在する場合)、レスポンスデータはキャッシュされません。

  • レスポンスがすでにキャッシュされていて、Cache-Control ヘッダーに no-cache 値を指定して新しいリクエストが実行された場合、304 (変更なし) で本文のないレスポンスが返されます。

このフィルターは、ルートごとにローカルレスポンスキャッシュを構成し、spring.cloud.gateway.filter.local-response-cache.enabled プロパティが有効になっている場合にのみ使用できます。また、グローバルに構成されたローカルレスポンスキャッシュも機能として利用できます。

キャッシュエントリの有効期限をオーバーライドする最初のパラメーター (秒は s、分は m、時間は h で表される) と、このルートのエントリを削除するキャッシュの最大サイズを設定する 2 番目のパラメーター (KBMBGB)。

次のリストは、ローカルレスポンスキャッシュ GatewayFilter を追加する方法を示しています。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
            .filters(f -> f.prefixPath("/httpbin")
                .localResponseCache(Duration.ofMinutes(30), "500MB")
            ).uri(uri))
        .build();
}

またはこれ

application.yaml
spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - LocalResponseCache=30m,500MB
このフィルターは、HTTP Cache-Control ヘッダーの max-age 値も自動的に計算します。元のレスポンスに max-age が存在する場合のみ、timeToLive 構成パラメーターで設定された秒数で値が書き換えられます。連続した呼び出しでは、この値は、レスポンスが期限切れになるまでの残りの秒数で再計算されます。
この機能を有効にするには、プロジェクトの依存関係として com.github.ben-manes.caffeine:caffeine と spring-boot-starter-cache を追加します。
プロジェクトでカスタム CacheManager Bean を作成する場合は、@Primary でマークするか、@Qualifier を使用して注入する必要があります。

6.11. MapRequestHeader GatewayFilter ファクトリ

MapRequestHeader GatewayFilter ファクトリは、fromHeader および toHeader パラメーターを取ります。新しい名前付きヘッダー(toHeader)が作成され、受信 http リクエストから既存の名前付きヘッダー(fromHeader)から値が抽出されます。入力ヘッダーが存在しない場合、フィルターは影響を与えません。新しい名前付きヘッダーがすでに存在する場合、その値は新しい値で拡張されます。次の例では、MapRequestHeader を構成します。

例 32: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: map_request_header_route
        uri: https://example.org
        filters:
        - MapRequestHeader=Blue, X-Request-Red

これにより、受信 HTTP リクエストの Blue ヘッダーから更新された値を使用して、ダウンストリームリクエストに X-Request-Red:<values> ヘッダーが追加されます。

6.12. ModifyRequestBody GatewayFilter ファクトリ

ゲートウェイによってダウンストリームに送信される前に、ModifyRequestBody フィルターを使用してリクエスト本文を変更できます。

このフィルターは、JavaDSL を使用してのみ構成できます。

次のリストは、リクエスト本文 GatewayFilter を変更する方法を示しています。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,
                    (exchange, s) -> Mono.just(new Hello(s.toUpperCase())))).uri(uri))
        .build();
}

static class Hello {
    String message;

    public Hello() { }

    public Hello(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
リクエストに本文がない場合、RewriteFilter は null に渡されます。Mono.empty() を返して、リクエストに欠落している本文を割り当てる必要があります。

6.13. ModifyResponseBody GatewayFilter ファクトリ

ModifyResponseBody フィルターを使用して、レスポンス本文をクライアントに送り返す前に変更できます。

このフィルターは、JavaDSL を使用してのみ構成できます。

次のリストは、レスポンス本文 GatewayFilter を変更する方法を示しています。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
            .filters(f -> f.prefixPath("/httpbin")
                .modifyResponseBody(String.class, String.class,
                    (exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
        .build();
}
レスポンスに本文がない場合、RewriteFilter は null に渡されます。Mono.empty() を返して、欠落している本文をレスポンスで割り当てる必要があります。

6.14. PrefixPath GatewayFilter ファクトリ

PrefixPath GatewayFilter ファクトリは、単一の prefix パラメーターを取ります。次の例では、PrefixPath GatewayFilter を構成します。

例 33: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

これにより、一致するすべてのリクエストのパスに /mypath のプレフィックスが付けられます。/hello へのリクエストは /mypath/hello に送信されます。

6.15. PreserveHostHeader GatewayFilter ファクトリ

PreserveHostHeader GatewayFilter ファクトリにはパラメーターがありません。このフィルターは、HTTP クライアントによって決定されたホストヘッダーではなく、元のホストヘッダーを送信する必要があるかどうかを決定するために、ルーティングフィルターがインスペクションするリクエスト属性を設定します。次の例では、PreserveHostHeader GatewayFilter を構成します。

例 34: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: preserve_host_route
        uri: https://example.org
        filters:
        - PreserveHostHeader

6.16. RedirectTo GatewayFilter ファクトリ

RedirectTo GatewayFilter ファクトリは 3 つのパラメーター statusurl、オプションで includeRequestParams を取ります。status パラメーターは、301 などの 300 シリーズリダイレクト HTTP コードである必要があります。url パラメーターは有効な URL である必要があります。これは Location ヘッダーの値です。includeRequestParams パラメーターは、リクエストクエリパラメーターを url に含める必要があるかどうかを示します。設定されていない場合は、false として扱われます。相対リダイレクトの場合は、ルート定義の URI として uri: no://op を使用する必要があります。次のリストは RedirectTo GatewayFilter を構成します。

例 35: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org

これにより、Location:https://acme.org ヘッダー付きのステータス 302 が送信され、リダイレクトが実行されます。

次の例では、includeRequestParams を true に設定して RedirectTo GatewayFilter を構成します。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - RedirectTo=302, https://acme.org, true

クエリ ?skip=10 を含むリクエストがゲートウェイに対して行われると、ゲートウェイはリダイレクトを実行するために Location:https://acme.org?skip=10 ヘッダーを含むステータス 302 を送信します。

6.17. RemoveJsonAttributesResponseBody GatewayFilter ファクトリ

RemoveJsonAttributesResponseBody GatewayFilter ファクトリは、検索する attribute names のコレクションを取得します。リストのオプションの最後のパラメーターは、ルートレベルで属性を削除するためのブール値にすることができます (パラメーター構成の最後に存在しない場合のデフォルト値 false)。または再帰的に (true)。属性を削除することにより、JSON 本文コンテンツに変換を適用する便利な方法を提供します。

次の例では、RemoveJsonAttributesResponseBody GatewayFilter を構成します。

例 36: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removejsonattributes_route
        uri: https://example.org
        filters:
        - RemoveJsonAttributesResponseBody=id,color

これにより、ルートレベルの JSON コンテンツボディから属性 "id" と "color" が削除されます。

次の例では、オプションの最後のパラメーターを使用する RemoveJsonAttributesResponseBody GatewayFilter を構成します。

例 37: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removejsonattributes_recursively_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - RemoveJsonAttributesResponseBody=id,color,true

これにより、任意のレベルで JSON コンテンツ本体から属性 "id" と "color" が削除されます。

6.18. RemoveRequestHeader GatewayFilter ファクトリ

RemoveRequestHeader GatewayFilter ファクトリは、name パラメーターを取ります。削除するヘッダーの名前です。次のリストは、RemoveRequestHeader GatewayFilter を構成します。

例 38: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestheader_route
        uri: https://example.org
        filters:
        - RemoveRequestHeader=X-Request-Foo

これにより、X-Request-Foo ヘッダーがダウンストリームに送信される前に削除されます。

6.19. RemoveRequestParameter GatewayFilter ファクトリ

RemoveRequestParameter GatewayFilter ファクトリは、name パラメーターを取ります。削除するクエリパラメーターの名前です。次の例では、RemoveRequestParameter GatewayFilter を構成します。

例 39: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removerequestparameter_route
        uri: https://example.org
        filters:
        - RemoveRequestParameter=red

これにより、red パラメーターがダウンストリームに送信される前に削除されます。

6.20. RemoveResponseHeader GatewayFilter ファクトリ

RemoveResponseHeader GatewayFilter ファクトリは、name パラメーターを取ります。削除するヘッダーの名前です。次のリストは、RemoveResponseHeader GatewayFilter を構成します。

例 40: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: removeresponseheader_route
        uri: https://example.org
        filters:
        - RemoveResponseHeader=X-Response-Foo

これにより、X-Response-Foo ヘッダーがゲートウェイクライアントに返される前に、レスポンスから削除されます。

あらゆる種類の機密ヘッダーを削除するには、必要なルートに対してこのフィルターを構成する必要があります。さらに、spring.cloud.gateway.default-filters を使用してこのフィルターを一度構成し、すべてのルートに適用することができます。

6.21. RequestHeaderSize GatewayFilter ファクトリ

RequestHeaderSize GatewayFilter ファクトリは、maxSize および errorHeaderName パラメーターを受け取ります。maxSize パラメーターは、リクエストヘッダーで許可される最大データサイズです (キーと値を含む)。errorHeaderName パラメーターは、エラーメッセージを含むレスポンスヘッダーの名前を設定します。デフォルトでは、これは "errorMessage" です。次のリストは、RequestHeaderSize GatewayFilter を構成します。

例 41: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: requestheadersize_route
        uri: https://example.org
        filters:
        - RequestHeaderSize=1000B

これにより、リクエストヘッダーのサイズが 1000 バイトを超える場合、ステータス 431 が送信されます。

6.22. RequestRateLimiter GatewayFilter ファクトリ

RequestRateLimiter GatewayFilter ファクトリは、RateLimiter 実装を使用して、現在のリクエストの続行が許可されているかどうかを判別します。そうでない場合は、HTTP 429 - Too Many Requests のステータス(デフォルト)が返されます。

このフィルターは、オプションの keyResolver パラメーターと、レートリミッターに固有のパラメーターを受け取ります ( このセクションで後述します )。

keyResolver は、KeyResolver インターフェースを実装する Bean です。構成では、SpEL を使用して Bean を名前で参照します。#{@myKeyResolver} は、myKeyResolver という名前の Bean を参照する SpEL 式です。次のリストは、KeyResolver インターフェースを示しています。

例 42: KeyResolver.java
public interface KeyResolver {
    Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver インターフェースにより、プラグ可能な戦略がリクエストを制限するための鍵を導き出すことができます。将来のマイルストーンリリースでは、いくつかの KeyResolver 実装があります。

KeyResolver のデフォルトの実装は PrincipalNameKeyResolver です。これは、ServerWebExchange から Principal を取得し、Principal.getName() を呼び出します。

デフォルトでは、KeyResolver がキーを見つけられない場合、リクエストは拒否されます。この動作は、spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true または false)および spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code プロパティを設定することで調整できます。

RequestRateLimiter は、「ショートカット」表記では構成できません。以下の例は無効です:

例 43: application.properties
# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

6.22.1. Redis RateLimiter

Redis の実装は、ストライプ (英語) で行われた作業に基づいています。spring-boot-starter-data-redis-reactive Spring Boot スターターを使用する必要があります。

使用されるアルゴリズムはトークンバケットアルゴリズム [Wikipedia] (英語) です。

redis-rate-limiter.replenishRate プロパティは、許可する 1 秒あたりのリクエスト数を定義します (リクエストのドロップなし)。これは、トークンバケットが満たされる速度です。

redis-rate-limiter.burstCapacity プロパティは、ユーザーが 1 秒間に許可されるリクエストの最大数です (ドロップされたリクエストはありません)。これは、トークンバケットが保持できるトークンの数です。この値をゼロに設定すると、すべてのリクエストがブロックされます。

redis-rate-limiter.requestedTokens プロパティは、リクエストにかかるトークンの数です。これは、リクエストごとにバケットから取得されたトークンの数であり、デフォルトは 1 です。

replenishRate と burstCapacity に同じ値を設定すると、安定したレートが実現されます。burstCapacity を replenishRate より高く設定することにより、一時的なバーストを許可できます。この場合、2 つのバーストが連続するとリクエストが破棄される (HTTP 429 - Too Many Requests) ため、レートリミッタはバースト間にある程度の時間を許可する必要があります ( replenishRate に従って)。次のリストでは、redis-rate-limiter を構成しています。

1 request/s 未満のレート制限は、replenishRate を必要なリクエスト数に設定し、requestedTokens を秒単位のタイムスパンに設定し、burstCapacity を replenishRate と requestedTokens の積に設定することによって達成されます。例: replenishRate=1requestedTokens=60burstCapacity=60 を設定すると、制限が 1 request/min になります。.application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20
            redis-rate-limiter.requestedTokens: 1

次の例では、Java で KeyResolver を構成します。

例 44: Config.java
@Bean
KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

これにより、ユーザーあたり 10 のリクエストレート制限が定義されます。20 のバーストが許可されますが、次の 1 秒間は 10 のリクエストしか使用できません。KeyResolver は、user リクエストパラメーターを取得する単純なものです。注: これは本番環境では推奨されません。

レートリミッタを、RateLimiter インターフェースを実装する Bean として定義することもできます。構成では、SpEL を使用して Bean を名前で参照できます。#{@myRateLimiter} は、myRateLimiter という名前の Bean を参照する SpEL 式です。次のリストは、前のリストで定義された KeyResolver を使用するレートリミッタを定義しています。

例 45: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: https://example.org
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@myRateLimiter}"
            key-resolver: "#{@userKeyResolver}"

6.23. RewriteLocationResponseHeader GatewayFilter ファクトリ

RewriteLocationResponseHeader GatewayFilter ファクトリは、Location レスポンスヘッダーの値を変更し、通常はバックエンド固有の詳細を取り除きます。stripVersionModelocationHeaderNamehostValueprotocolsRegex パラメーターを取ります。次のリストでは、RewriteLocationResponseHeader GatewayFilter を構成しています。

例 46: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewritelocationresponseheader_route
        uri: http://example.org
        filters:
        - RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

例: POST api.example.com/some/object/name (英語) のリクエストの場合、object-service.prod.example.net/v2/some/object/id (英語)  の Location レスポンスヘッダー値は api.example.com/some/object/id (英語) として書き換えられます。

stripVersionMode パラメーターには、次の可能な値があります: NEVER_STRIPAS_IN_REQUEST (デフォルト)、ALWAYS_STRIP

  • NEVER_STRIP: 元のリクエストパスにバージョンが含まれていない場合でも、バージョンは削除されません。

  • AS_IN_REQUEST: バージョンは、元のリクエストパスにバージョンが含まれていない場合にのみ削除されます。

  • ALWAYS_STRIP: 元のリクエストパスにバージョンが含まれている場合でも、バージョンは常に削除されます。

hostValue パラメーターが指定されている場合は、レスポンス Location ヘッダーの host:port 部分を置き換えるために使用されます。指定されていない場合は、Host リクエストヘッダーの値が使用されます。

protocolsRegex パラメーターは、プロトコル名が一致する有効な正規表現 String である必要があります。一致しない場合、フィルターは何もしません。デフォルトは http|https|ftp|ftps です。

6.24. RewritePath GatewayFilter ファクトリ

RewritePath GatewayFilter ファクトリは、パス regexp パラメーターと replacement パラメーターを取ります。これは、Java 正規表現を使用して、リクエストパスを柔軟に書き換えます。次のリストは、RewritePath GatewayFilter を構成します。

例 47: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: https://example.org
        predicates:
        - Path=/red/**
        filters:
        - RewritePath=/red/?(?<segment>.*), /$\{segment}

/red/blue のリクエストパスの場合、これにより、ダウンストリームリクエストを行う前にパスが /blue に設定されます。YAML 仕様のため、$ は $\ に置き換える必要があることに注意してください。

6.25. RewriteRequestParameter GatewayFilter ファクトリ

RewriteRequestParameter GatewayFilter ファクトリは、name パラメーターと replacement パラメーターを受け取ります。指定された name のリクエストパラメーターの値を書き換えます。同じ name を持つリクエストパラメーターが複数設定されている場合、単一の値に置き換えられます。リクエストパラメーターが見つからない場合、変更は行われません。次のリストは、RewriteRequestParameter GatewayFilter を構成します。

例 48: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewriterequestparameter_route
        uri: https://example.org
        predicates:
        - Path=/products
        filters:
        - RewriteRequestParameter=campaign,fall2023

/products?campaign=old へのリクエストの場合、これによりリクエストパラメーターが campaign=fall2023 に設定されます。

6.26. RewriteResponseHeader GatewayFilter ファクトリ

RewriteResponseHeader GatewayFilter ファクトリは nameregexpreplacement パラメーターを取ります。Java 正規表現を使用して、レスポンスヘッダー値を柔軟に書き換えます。次の例では、RewriteResponseHeader GatewayFilter を構成します。

例 49: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: rewriteresponseheader_route
        uri: https://example.org
        filters:
        - RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***

/42?user=ford&password=omg!what&flag=true のヘッダー値の場合、ダウンストリームリクエストを行った後に /42?user=ford&password=***&flag=true に設定されます。YAML 仕様のため、$ を意味するために $\ を使用する必要があります。

6.27. SaveSession GatewayFilter ファクトリ

SaveSession GatewayFilter ファクトリは、コールをダウンストリームに転送する前に WebSession::save 操作を強制します。これは、遅延データストアで Spring Session のようなものを使用する場合に特に役立ちます。転送された呼び出しを行う前に、セッション状態が保存されていることを確認する必要があります。次の例では、SaveSession GatewayFilter を構成します。

例 50: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: save_session
        uri: https://example.org
        predicates:
        - Path=/foo/**
        filters:
        - SaveSession

Spring Security を Spring Session と統合し、セキュリティの詳細がリモートプロセスに転送されていることを確認したい場合、これは重要です。

6.28. SecureHeaders GatewayFilter ファクトリ

SecureHeaders GatewayFilter ファクトリは、このブログ投稿 (英語) で行われた推奨に従って、レスポンスにいくつかのヘッダーを追加します。

次のヘッダー(デフォルト値で表示)が追加されました。

  • X-Xss-Protection:1 (mode=block)

  • Strict-Transport-Security (max-age=631138519)

  • X-Frame-Options (DENY)

  • X-Content-Type-Options (nosniff)

  • Referrer-Policy (no-referrer)

  • Content-Security-Policy (default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline)'

  • X-Download-Options (noopen)

  • X-Permitted-Cross-Domain-Policies (none)

デフォルト値を変更するには、spring.cloud.gateway.filter.secure-headers 名前空間に適切なプロパティを設定します。次のプロパティを使用できます。

  • xss-protection-header

  • strict-transport-security

  • frame-options

  • content-type-options

  • referrer-policy

  • content-security-policy

  • download-options

  • permitted-cross-domain-policies

デフォルト値を無効にするには、spring.cloud.gateway.filter.secure-headers.disable プロパティをコンマ区切りの値で設定します。次の例は、その方法を示しています。

spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security
セキュアヘッダーを無効にするには、セキュアヘッダーの小文字のフルネームを使用する必要があります。

6.29. SetPath GatewayFilter ファクトリ

SetPath GatewayFilter ファクトリは、パス template パラメーターを取ります。パスのテンプレート化されたセグメントを許可することにより、リクエストパスを操作する簡単な方法を提供します。これは、Spring Framework の URI テンプレートを使用します。複数の一致するセグメントが許可されます。次の例では、SetPath GatewayFilter を構成します。

例 51: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setpath_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment}
        filters:
        - SetPath=/{segment}

/red/blue のリクエストパスの場合、これにより、ダウンストリームリクエストを行う前にパスが /blue に設定されます。

6.30. SetRequestHeader GatewayFilter ファクトリ

SetRequestHeader GatewayFilter ファクトリは、name および value パラメーターを取ります。次のリストは、SetRequestHeader GatewayFilter を構成します。

例 52: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        filters:
        - SetRequestHeader=X-Request-Red, Blue

この GatewayFilter は、すべてのヘッダーを指定された名前に (追加するのではなく) 置き換えます。ダウンストリームサーバーが X-Request-Red:1234 で応答した場合は、ダウンストリームサービスが受け取るものである X-Request-Red:Blue に置き換えられます。

SetRequestHeader は、パスまたはホストの照合に使用される URI 変数を認識しています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する SetRequestHeader GatewayFilter を構成します。

例 53: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setrequestheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetRequestHeader=foo, bar-{segment}

6.31. SetResponseHeader GatewayFilter ファクトリ

SetResponseHeader GatewayFilter ファクトリは、name および value パラメーターを取ります。次のリストは、SetResponseHeader GatewayFilter を構成します。

例 54: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        filters:
        - SetResponseHeader=X-Response-Red, Blue

この GatewayFilter は、すべてのヘッダーを指定された名前に (追加するのではなく) 置き換えます。ダウンストリームサーバーが X-Response-Red:1234 で応答した場合、ゲートウェイクライアントが受け取るものである X-Response-Red:Blue に置き換えられます。

SetResponseHeader は、パスまたはホストの照合に使用される URI 変数を認識しています。URI 変数は値で使用でき、実行時に展開されます。次の例では、変数を使用する SetResponseHeader GatewayFilter を構成します。

例 55: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setresponseheader_route
        uri: https://example.org
        predicates:
        - Host: {segment}.myhost.org
        filters:
        - SetResponseHeader=foo, bar-{segment}

6.32. SetStatus GatewayFilter ファクトリ

SetStatus GatewayFilter ファクトリは、単一のパラメーター status を取ります。有効な Spring HttpStatus である必要があります。これは、整数値 404 または列挙の文字列表現 NOT_FOUND の場合があります。次のリストは、SetStatus GatewayFilter を構成します。

例 56: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setstatusstring_route
        uri: https://example.org
        filters:
        - SetStatus=UNAUTHORIZED
      - id: setstatusint_route
        uri: https://example.org
        filters:
        - SetStatus=401

いずれの場合も、レスポンスの HTTP ステータスは 401 に設定されます。

SetStatus GatewayFilter を構成して、プロキシされたリクエストから元の HTTP ステータスコードをレスポンスのヘッダーに返すことができます。次のプロパティで構成されている場合、ヘッダーはレスポンスに追加されます。

例 57: application.yml
spring:
  cloud:
    gateway:
      set-status:
        original-status-header-name: original-http-status

6.33. StripPrefix GatewayFilter ファクトリ

StripPrefix GatewayFilter ファクトリは、1 つのパラメーター parts を取ります。parts パラメーターは、リクエストをダウンストリームに送信する前にリクエストから取り除くパス内のパーツの数を示します。次のリストは、StripPrefix GatewayFilter を構成します。

例 58: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: https://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

/name/blue/red へのゲートウェイを介してリクエストが行われると、nameservice に対して行われたリクエストは nameservice/red (英語) のようになります。

6.34. Retry GatewayFilter ファクトリ

Retry GatewayFilter ファクトリは、以下のパラメーターをサポートします。

  • retries: 試行する必要のある再試行の回数。

  • statusesorg.springframework.http.HttpStatus を使用して表される、再試行する必要のある HTTP ステータスコード。

  • methodsorg.springframework.http.HttpMethod を使用して表される、再試行する必要のある HTTP メソッド。

  • seriesorg.springframework.http.HttpStatus.Series を使用して表される、再試行される一連のステータスコード。

  • exceptions: 再試行する必要があるスローされた例外のリスト。

  • backoff: 再試行用に構成された指数バックオフ。再試行は、firstBackoff * (factor ^ n) のバックオフ間隔の後に実行されます。ここで、n は反復です。maxBackoff が構成されている場合、適用される最大バックオフは maxBackoff に制限されます。basedOnPreviousValue が true の場合、バックオフは prevBackoff * factor を使用して計算されます。

有効になっている場合、Retry フィルターには次のデフォルトが構成されています。

  • retries: 3 回

  • series: 5XX シリーズ

  • methods: GET メソッド

  • exceptionsIOException および TimeoutException

  • backoff: 無効

次のリストは、再試行 GatewayFilter を構成します。

例 59: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: retry_test
        uri: http://localhost:8080/flakey
        predicates:
        - Host=*.retry.com
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: BAD_GATEWAY
            methods: GET,POST
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false
forward: プレフィックス付き URL で再試行フィルターを使用する場合は、エラーが発生した場合にクライアントにレスポンスが送信されてコミットされる可能性のある処理を行わないように、ターゲットエンドポイントを慎重に記述する必要があります。例: ターゲットエンドポイントがアノテーション付きコントローラーである場合、ターゲットコントローラーメソッドはエラーステータスコードで ResponseEntity を返さないようにする必要があります。代わりに、Exception をスローするか、エラーを通知する必要があります(たとえば、Mono.error(ex) の戻り値を介して)。これは、再試行によって処理するように再試行フィルターを構成できます。
本文のある HTTP メソッドで再試行フィルターを使用すると、本文がキャッシュされ、ゲートウェイのメモリが制限されます。本文は、ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR で定義されたリクエスト属性にキャッシュされます。オブジェクトの型は org.springframework.core.io.buffer.DataBuffer です。

簡略化された「ショートカット」表記は、単一の status および method で追加できます。

次の 2 つの例は同等です。

例 60: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: retry_route
        uri: https://example.org
        filters:
        - name: Retry
          args:
            retries: 3
            statuses: INTERNAL_SERVER_ERROR
            methods: GET
            backoff:
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false

      - id: retryshortcut_route
        uri: https://example.org
        filters:
        - Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false

6.35. RequestSize GatewayFilter ファクトリ

リクエストサイズが許容限度を超える場合、RequestSize GatewayFilter ファクトリは、リクエストがダウンストリームサービスに到達するのを制限できます。フィルターは maxSize パラメーターを取ります。maxSize は DataSize 型であるため、値は、数値の後に "KB" や "MB" などのオプションの DataUnit サフィックスを付けたものとして定義できます。デフォルトはバイトの "B" です。これは、バイト単位で定義されたリクエストの許容サイズ制限です。次のリストは、RequestSize GatewayFilter を構成します。

例 61: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: request_size_route
        uri: http://localhost:8080/upload
        predicates:
        - Path=/upload
        filters:
        - name: RequestSize
          args:
            maxSize: 5000000

RequestSize GatewayFilter ファクトリは、サイズが原因でリクエストが拒否された場合に、レスポンスステータスを 413 Payload Too Large として設定し、ヘッダー errorMessage を追加します。次の例は、そのような errorMessage を示しています。

errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
ルート定義でフィルター引数として指定されていない場合、デフォルトのリクエストサイズは 5MB に設定されます。

6.36. SetRequestHostHeader GatewayFilter ファクトリ

ホストヘッダーをオーバーライドする必要がある特定の状況があります。この場合、SetRequestHostHeader GatewayFilter ファクトリは、既存のホストヘッダーを指定された値に置き換えることができます。フィルターは host パラメーターを取ります。次のリストでは、SetRequestHostHeader GatewayFilter を構成しています。

例 62: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: set_request_host_header_route
        uri: http://localhost:8080/headers
        predicates:
        - Path=/headers
        filters:
        - name: SetRequestHostHeader
          args:
            host: example.org

SetRequestHostHeader GatewayFilter ファクトリは、ホストヘッダーの値を example.org に置き換えます。

6.37. TokenRelay GatewayFilter ファクトリ

トークンリレーは、OAuth2 コンシューマーがクライアントとして機能し、受信トークンを発信リソースリクエストに転送する場所です。コンシューマーは、純粋なクライアント(SSO アプリケーションなど)またはリソースサーバーにすることができます。

Spring Cloud Gateway は、プロキシしているサービスに OAuth2 アクセストークンをダウンストリームに転送できます。この機能をゲートウェイに追加するには、次のように TokenRelayGatewayFilterFactory を追加する必要があります。

App.java
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route("resource", r -> r.path("/resource")
                    .filters(f -> f.tokenRelay())
                    .uri("http://localhost:9000"))
            .build();
}

またはこれ

application.yaml
spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

そして、(ユーザーのログインとトークンの取得に加えて)認証トークンをサービス(この場合は /resource)にダウンストリームで渡します。

Spring Cloud Gateway でこれを有効にするには、次の依存関係を追加します

  • org.springframework.boot:spring-boot-starter-oauth2-client

それはどのように機能しますか? {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter] は、現在認証されているユーザーからアクセストークンを抽出し、ダウンストリームリクエストのリクエストヘッダーに配置します。

完全に機能するサンプルについては、このプロジェクト [GitHub] (英語) を参照してください。

TokenRelayGatewayFilterFactory Bean は、ReactiveClientRegistrationRepository Bean の作成をトリガーする適切な spring.security.oauth2.client.* プロパティが設定されている場合にのみ作成されます。
TokenRelayGatewayFilterFactory によって使用される ReactiveOAuth2AuthorizedClientService のデフォルトの実装は、インメモリデータストアを使用します。より堅牢なソリューションが必要な場合は、独自の実装 ReactiveOAuth2AuthorizedClientService を提供する必要があります。

6.38. デフォルトフィルター

フィルターを追加してすべてのルートに適用するには、spring.cloud.gateway.default-filters を使用できます。このプロパティは、フィルターのリストを取ります。次のリストは、デフォルトのフィルターのセットを定義しています。

例 63: application.yml
spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin

7. グローバルフィルター

GlobalFilter インターフェースには、GatewayFilter と同じ署名があります。これらは、すべてのルートに条件付きで適用される特別なフィルターです。

このインターフェースとその使用箇所は、将来のマイルストーンリリースで変更される可能性があります。

7.1. グローバルフィルターと GatewayFilter の組み合わせオーダー

リクエストがルートに一致すると、フィルタリング Web ハンドラーは GlobalFilter のすべてのインスタンスと GatewayFilter のすべてのルート固有のインスタンスをフィルターチェーンに追加します。この結合されたフィルターチェーンは、getOrder() メソッドを実装することで設定できる org.springframework.core.Ordered インターフェースによってソートされます。

Spring Cloud Gateway は、フィルターロジック実行の「前」フェーズと「後」フェーズを区別するため(使い方を参照)、優先順位が最も高いフィルターは、「前」フェーズの最初と「後」フェーズの最後です。

次のリストは、フィルターチェーンを構成します。

例 64: ExampleConfiguration.java
@Bean
public GlobalFilter customFilter() {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

7.2. ゲートウェイメトリクスフィルター

ゲートウェイメトリクスを有効にするには、プロジェクトの依存関係として spring-boot-starter-actuator を追加します。次に、デフォルトで、spring.cloud.gateway.metrics.enabled プロパティが false に設定されていない限り、ゲートウェイメトリクスフィルターが実行されます。このフィルターは、次のタグを持つ spring.cloud.gateway.requests という名前のタイマーメトリクスを追加します。

  • routeId: ルート ID。

  • routeUri: API がルーティングされる URI。

  • outcome: HttpStatus.Series (Javadoc) によって分類された結果。

  • status: クライアントに返されたリクエストの HTTP ステータス。

  • httpStatusCode: クライアントに返されたリクエストの HTTP ステータス。

  • httpMethod: リクエストに使用される HTTP メソッド。

さらに、spring.cloud.gateway.metrics.tags.path.enabled プロパティ (デフォルトでは false) を介して、パスタグを使用して追加のメトリクスをアクティブ化できます。

  • path: リクエストのパス。

これらのメトリクスは、/actuator/metrics/spring.cloud.gateway.requests からスクレイピングできるようになり、Prometheus と簡単に統合して Grafana ダッシュボードを作成できます。

プロメテウスエンドポイントを有効にするには、プロジェクトの依存関係として micrometer-registry-prometheus を追加します。

7.3. ローカルレスポンスキャッシュフィルター

関連するプロパティが有効になっている場合、LocalResponseCache が実行されます。

  • spring.cloud.gateway.global-filter.local-response-cache.enabled: すべてのルートのグローバルキャッシュを有効にします

  • spring.cloud.gateway.filter.local-response-cache.enabled: 関連付けられたフィルターをアクティブにして、ルートレベルで使用します

この機能は、次の条件を満たすすべてのレスポンスに対して Caffeine を使用してローカルキャッシュを有効にします。

  • リクエストはボディレス GET です。

  • レスポンスには、HTTP 200 (OK)、HTTP 206 (部分的なコンテンツ)、または HTTP 301 (完全に移動) のいずれかのステータスコードがあります。

  • HTTP Cache-Control ヘッダーはキャッシングを許可します (つまり、次のいずれの値も持たないことを意味します: リクエストに存在する no-store およびレスポンスに存在する no-store または private )。

次の 2 つの構成パラメーターを受け入れます。

  • spring.cloud.gateway.filter.local-response-cache.size: このルートのエントリを削除するためのキャッシュの最大サイズを設定します (KB、MB、GB 単位)。

  • spring.cloud.gateway.filter.local-response-cache.time-to-live キャッシュエントリの有効期限を設定します (秒は s、分は m、時間は h で表されます)。

これらのパラメーターのいずれも構成されていないが、グローバルフィルターが有効になっている場合、デフォルトでは、キャッシュされたレスポンスに対して 5 分間の存続時間が構成されます。

このフィルターは、HTTP Cache-Control ヘッダーの max-age 値の自動計算も実装します。元のレスポンスに max-age が存在する場合、値は timeToLive 構成パラメーターで設定された秒数で書き換えられます。後続の呼び出しでは、この値は、レスポンスが期限切れになるまでの残りの秒数で再計算されます。

spring.cloud.gateway.global-filter.local-response-cache.enabled を false に設定すると、すべてのルートのローカルレスポンスキャッシュが非アクティブになり、LocalResponseCache フィルターはルートレベルでこの機能を使用できるようにします。

この機能を有効にするには、プロジェクトの依存関係として com.github.ben-manes.caffeine:caffeine と spring-boot-starter-cache を追加します。
プロジェクトでカスタム CacheManager Bean を作成する場合は、@Primary でマークするか、@Qualifier を使用して注入する必要があります。

7.4. フォワードルーティングフィルター

ForwardRoutingFilter は、交換属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR で URI を探します。URL に forward スキーム(forward:///localendpoint など)がある場合、URL は Spring DispatcherHandler を使用してリクエストを処理します。リクエスト URL のパス部分は、フォワード URL のパスで上書きされます。変更されていない元の URL は、ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 属性のリストに追加されます。

7.5. Netty ルーティングフィルター

Netty ルーティングフィルターは、ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換属性にある URL に http または https スキームがある場合に実行されます。Netty HttpClient を使用して、ダウンストリームプロキシリクエストを行います。レスポンスは、後のフィルターで使用するために ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交換属性に入れられます。(同じ機能を実行するが Netty を必要としない実験的な WebClientHttpRoutingFilter もあります。)

7.6. Netty 書き込みレスポンスフィルター

ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交換属性に Netty HttpClientResponse がある場合、NettyWriteResponseFilter が実行されます。他のすべてのフィルターが完了した後に実行され、プロキシレスポンスをゲートウェイクライアントレスポンスに書き戻します。(同じ機能を実行するが Netty を必要としない実験的な WebClientWriteResponseFilter もあります。)

7.7. ReactiveLoadBalancerClientFilter

ReactiveLoadBalancerClientFilter は、ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR という名前の交換属性で URI を探します。URL に lb スキーム(lb://myservice など)がある場合、URL は Spring Cloud ReactorLoadBalancer を使用して名前(この例では myservice)を実際のホストとポートに解決し、同じ属性の URI を置き換えます。変更されていない元の URL は、ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 属性のリストに追加されます。フィルターは、ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 属性も調べて、lb と等しいかどうかを確認します。その場合、同じルールが適用されます。次のリストは、ReactiveLoadBalancerClientFilter を構成します。

例 65: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://service
        predicates:
        - Path=/service/**
デフォルトでは、サービスインスタンスが ReactorLoadBalancer で見つからない場合、503 が返されます。spring.cloud.gateway.loadbalancer.use404=true を設定することにより、404 を返すようにゲートウェイを構成できます。
ReactiveLoadBalancerClientFilter から返された ServiceInstance の isSecure 値は、ゲートウェイに対して行われたリクエストで指定されたスキームをオーバーライドします。例: リクエストが HTTPS を介してゲートウェイに到着したが、ServiceInstance が安全でないことを示している場合、ダウンストリームリクエストは HTTP を介して行われます。逆の状況も当てはまります。ただし、ゲートウェイ構成のルートに GATEWAY_SCHEME_PREFIX_ATTR が指定されている場合、プレフィックスは削除され、ルート URL からの結果のスキームが ServiceInstance 構成を上書きします。
ゲートウェイは、すべての LoadBalancer 機能をサポートします。Spring Cloud Commons ドキュメントでそれらについてさらに読むことができます。

7.8. RouteToRequestUrl フィルター

ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 交換属性に Route オブジェクトがある場合、RouteToRequestUrlFilter が実行されます。リクエスト URI に基づいて新しい URI を作成しますが、Route オブジェクトの URI 属性で更新されます。新しい URI は ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換属性に配置されます。

URI に lb:ws://serviceid などのスキームプレフィックスがある場合、lb スキームは URI から削除され、後でフィルターチェーンで使用するために ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR に配置されます。

7.9. Websocket ルーティングフィルター

ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交換属性にある URL に ws または wss スキームがある場合、WebSocket ルーティングフィルターが実行されます。Spring WebSocket インフラストラクチャを使用して、WebSocket リクエストをダウンストリームに転送します。

URI の前に lb:ws://serviceid などの lb を付けることで、WebSocket の負荷を分散できます。

通常の HTTP のフォールバックとして SockJS [GitHub] (英語) を使用する場合は、通常の HTTP ルートと WebSocket ルートを構成する必要があります。

次のリストは、WebSocket ルーティングフィルターを構成します。

例 66: application.yml
spring:
  cloud:
    gateway:
      routes:
      # SockJS route
      - id: websocket_sockjs_route
        uri: http://localhost:3001
        predicates:
        - Path=/websocket/info/**
      # Normal Websocket route
      - id: websocket_route
        uri: ws://localhost:3001
        predicates:
        - Path=/websocket/**

7.10. 交換をルーティング済みとしてマークする

ゲートウェイが ServerWebExchange をルーティングした後、交換属性に gatewayAlreadyRouted を追加することにより、その交換を「ルーティング済み」としてマークします。リクエストがルーティング済みとしてマークされると、他のルーティングフィルターはリクエストを再度ルーティングせず、基本的にフィルターをスキップします。交換をルーティング済みとしてマークしたり、交換がすでにルーティングされているかどうかを確認したりするために使用できる便利なメソッドがあります。

  • ServerWebExchangeUtils.isAlreadyRouted は、ServerWebExchange オブジェクトを受け取り、それが「ルーティング」されているかどうかを確認します。

  • ServerWebExchangeUtils.setAlreadyRouted は ServerWebExchange オブジェクトを受け取り、それを「ルーティング済み」としてマークします。

8. HttpHeadersFilters

HttpHeadersFilters は、NettyRoutingFilter などでリクエストをダウンストリームに送信する前にリクエストに適用されます。

8.1. 転送ヘッダーフィルター

Forwarded ヘッダーフィルターは、ダウンストリームサービスに送信する Forwarded ヘッダーを作成します。現在のリクエストの Host ヘッダー、スキーム、ポートを既存の Forwarded ヘッダーに追加します。

8.2. RemoveHopByHop ヘッダーフィルター

RemoveHopByHop ヘッダーフィルターは、転送されたリクエストからヘッダーを削除します。削除されるヘッダーのデフォルトリストは、IETF (英語) からのものです。

デフォルトで削除されるヘッダーは次のとおりです。
  • 接続

  • キープアライブ

  • プロキシ認証

  • プロキシ認証

  • TE

  • トレーラー

  • 転送エンコーディング

  • アップグレード

これを変更するには、spring.cloud.gateway.filter.remove-hop-by-hop.headers プロパティを削除するヘッダー名のリストに設定します。

8.3. XForwarded ヘッダーフィルター

XForwarded ヘッダーフィルターは、ダウンストリームサービスに送信するさまざまな X-Forwarded-* ヘッダーを作成します。現在のリクエストの Host ヘッダー、スキーム、ポート、パスを使用して、さまざまなヘッダーを作成します。

個々のヘッダーの作成は、次のブールプロパティ(デフォルトは true)によって制御できます。

  • spring.cloud.gateway.x-forwarded.for-enabled

  • spring.cloud.gateway.x-forwarded.host-enabled

  • spring.cloud.gateway.x-forwarded.port-enabled

  • spring.cloud.gateway.x-forwarded.proto-enabled

  • spring.cloud.gateway.x-forwarded.prefix-enabled

複数のヘッダーの追加は、次のブールプロパティ(デフォルトは true)によって制御できます。

  • spring.cloud.gateway.x-forwarded.for-append

  • spring.cloud.gateway.x-forwarded.host-append

  • spring.cloud.gateway.x-forwarded.port-append

  • spring.cloud.gateway.x-forwarded.proto-append

  • spring.cloud.gateway.x-forwarded.prefix-append

9. TLS と SSL

ゲートウェイは、通常の Spring サーバー構成に従って、HTTPS でリクエストをリッスンできます。次の例は、その方法を示しています。

例 67: application.yml
server:
  ssl:
    enabled: true
    key-alias: scg
    key-store-password: scg1234
    key-store: classpath:scg-keystore.p12
    key-store-type: PKCS12

ゲートウェイルートは、HTTP バックエンドと HTTPS バックエンドの両方にルーティングできます。HTTPS バックエンドにルーティングする場合は、次の構成ですべてのダウンストリーム証明書を信頼するようにゲートウェイを構成できます。

例 68: application.yml
spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          useInsecureTrustManager: true

安全でないトラストマネージャーの使用は、本番環境には適していません。本番デプロイの場合、次の構成で信頼できる既知の証明書のセットを使用してゲートウェイを構成できます。

例 69: application.yml
spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          trustedX509Certificates:
          - cert1.pem
          - cert2.pem

Spring Cloud Gateway に信頼できる証明書がプロビジョニングされていない場合は、デフォルトのトラストストアが使用されます(javax.net.ssl.trustStore システムプロパティを設定することでオーバーライドできます)。

9.1. TLS ハンドシェイク

ゲートウェイは、バックエンドへのルーティングに使用するクライアントプールを維持します。HTTPS を介して通信する場合、クライアントは TLS ハンドシェイクを開始します。このハンドシェイクには、いくつかのタイムアウトが関連付けられています。これらのタイムアウトは次のように構成できます(デフォルトが表示されています)。

例 70: application.yml
spring:
  cloud:
    gateway:
      httpclient:
        ssl:
          handshake-timeout-millis: 10000
          close-notify-flush-timeout-millis: 3000
          close-notify-read-timeout-millis: 0

10. 構成

Spring Cloud Gateway の構成は、RouteDefinitionLocator インスタンスのコレクションによって駆動されます。次のリストは、RouteDefinitionLocator インターフェースの定義を示しています。

例 71: RouteDefinitionLocator.java
public interface RouteDefinitionLocator {
    Flux<RouteDefinition> getRouteDefinitions();
}

デフォルトでは、PropertiesRouteDefinitionLocator は Spring Boot の @ConfigurationProperties メカニズムを使用してプロパティをロードします。

以前の構成例はすべて、名前付き引数ではなく位置引数を使用するショートカット表記を使用しています。次の 2 つの例は同等です。

例 72: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: setstatus_route
        uri: https://example.org
        filters:
        - name: SetStatus
          args:
            status: 401
      - id: setstatusshortcut_route
        uri: https://example.org
        filters:
        - SetStatus=401

ゲートウェイの一部の使用箇所では、プロパティは適切ですが、一部の本番ユースケースでは、データベースなどの外部ソースから構成をロードすることでメリットが得られます。将来のマイルストーンバージョンには、Redis、MongoDB、Cassandra などの Spring Data リポジトリに基づく RouteDefinitionLocator 実装が含まれる予定です。

10.1. RouteDefinition メトリクス

RouteDefinition メトリクスを有効にするには、プロジェクトの依存関係として spring-boot-starter-actuator を追加します。次に、デフォルトでは、プロパティ spring.cloud.gateway.metrics.enabled が true に設定されている限り、メトリクスが使用可能になります。spring.cloud.gateway.routes.count という名前のゲージメトリクスが追加されます。その値は RouteDefinitions の数です。このメトリクスは、/actuator/metrics/spring.cloud.gateway.routes.count から入手できます。

11. ルートメタデータ構成

次のように、メタデータを使用して、各ルートに追加のパラメーターを構成できます。

例 73: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: route_with_metadata
        uri: https://example.org
        metadata:
          optionName: "OptionValue"
          compositeObject:
            name: "value"
          iAmNumber: 1

次のように、エクスチェンジからすべてのメタデータプロパティを取得できます。

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);

12. Http タイムアウト構成

Http タイムアウト(レスポンスと接続)は、すべてのルートに対して構成でき、特定のルートごとにオーバーライドできます。

12.1. グローバルタイムアウト

グローバル http タイムアウトを設定するには:
 connect-timeout はミリ秒単位で指定する必要があります。
 response-timeout は java.time.Duration として指定する必要があります

グローバル http タイムアウトの例
spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

12.2. ルートごとのタイムアウト

ルートごとのタイムアウトを設定するには:
 connect-timeout はミリ秒単位で指定する必要があります。
 response-timeout はミリ秒単位で指定する必要があります。

ルートごとの http は、構成を介して構成をタイムアウトします
      - id: per_route_timeouts
        uri: https://example.org
        predicates:
          - name: Path
            args:
              pattern: /delay/{timeout}
        metadata:
          response-timeout: 200
          connect-timeout: 200
JavaDSL を使用したルートごとのタイムアウト設定
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;

      @Bean
      public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
         return routeBuilder.routes()
               .route("test1", r -> {
                  return r.host("*.somehost.org").and().path("/somepath")
                        .filters(f -> f.addRequestHeader("header1", "header-value-1"))
                        .uri("http://someuri")
                        .metadata(RESPONSE_TIMEOUT_ATTR, 200)
                        .metadata(CONNECT_TIMEOUT_ATTR, 200);
               })
               .build();
      }

負の値を持つルートごとの response-timeout は、グローバル response-timeout 値を無効にします。

      - id: per_route_timeouts
        uri: https://example.org
        predicates:
          - name: Path
            args:
              pattern: /delay/{timeout}
        metadata:
          response-timeout: -1

13. Fluent Java Routes API

Java での単純な構成を可能にするために、RouteLocatorBuilder Bean には流れるような API が含まれています。次のリストは、それがどのように機能するかを示しています。

例 74: GatewaySampleApplication.java
// static imports from GatewayFilters and RoutePredicates
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
    return builder.routes()
            .route(r -> r.host("**.abc.org").and().path("/image/png")
                .filters(f ->
                        f.addResponseHeader("X-TestHeader", "foobar"))
                .uri("http://httpbin.org:80")
            )
            .route(r -> r.path("/image/webp")
                .filters(f ->
                        f.addResponseHeader("X-AnotherHeader", "baz"))
                .uri("http://httpbin.org:80")
                .metadata("key", "value")
            )
            .route(r -> r.order(-1)
                .host("**.throttle.org").and().path("/get")
                .filters(f -> f.filter(throttle.apply(1,
                        1,
                        10,
                        TimeUnit.SECONDS)))
                .uri("http://httpbin.org:80")
                .metadata("key", "value")
            )
            .build();
}

このスタイルでは、より多くのカスタム述語アサーションも可能です。RouteDefinitionLocator Bean によって定義された述語は、論理 and を使用して結合されます。流れるような JavaAPI を使用することにより、Predicate クラスで and()or()negate() 演算子を使用できます。

14. DiscoveryClient ルート定義ロケーター

DiscoveryClient 互換のサービスレジストリに登録されているサービスに基づいてルートを作成するようにゲートウェイを設定できます。

これを有効にするには、spring.cloud.gateway.discovery.locator.enabled=true を設定し、DiscoveryClient 実装 (Netflix Eureka、Consul、Zookeeper など) がクラスパス上にあり、有効になっていることを確認します。

14.1. DiscoveryClient ルートの述語とフィルターの構成

デフォルトでは、ゲートウェイは DiscoveryClient で作成されたルートに対して単一の述語とフィルターを定義します。

デフォルトの述語は、パターン /serviceId/** で定義されたパス述語です。ここで、serviceId は、DiscoveryClient からのサービスの ID です。

デフォルトのフィルターは、正規表現 /serviceId/?(?<remaining>.*) と置換 /${remaining} を使用した書き換えパスフィルターです。これにより、リクエストがダウンストリームに送信される前に、パスからサービス ID が削除されます。

DiscoveryClient ルートで使用される述語またはフィルターをカスタマイズする場合は、spring.cloud.gateway.discovery.locator.predicates[x] および spring.cloud.gateway.discovery.locator.filters[y] を設定します。その際、その機能を維持したい場合は、前に示したデフォルトの述語とフィルターを必ず含める必要があります。次の例は、これがどのように見えるかを示しています。

例 75: application.properties
spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

15. Reactor Netty アクセスログ

Reactor Netty アクセスログを有効にするには、-Dreactor.netty.http.server.accessLogEnabled=true を設定します。

Spring Boot プロパティではなく、Java システムプロパティである必要があります。

個別のアクセスログファイルを持つようにログシステムを構成できます。次の例では、Logback 構成を作成します。

例 76: logback.xml
    <appender name="accessLog" class="ch.qos.logback.core.FileAppender">
        <file>access_log.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>
    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="accessLog" />
    </appender>

    <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
        <appender-ref ref="async"/>
    </logger>

16. CORS 構成

CORS の動作をグローバルに、またはルートごとに制御するようにゲートウェイを構成できます。どちらも同じ可能性を提供します。

16.1. グローバル CORS 構成

「グローバル」CORS 設定は、URL パターンの Spring Framework CorsConfiguration (Javadoc) へのマップです。次の例では、CORS を構成します。

例 77: application.yml
spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "https://docs.spring.io"
            allowedMethods:
            - GET

前の例では、すべての GET リクエストパスに対して docs.spring.io から発信されたリクエストからの CORS リクエストが許可されています。

一部のゲートウェイルート述語によって処理されないリクエストに同じ CORS 構成を提供するには、spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping プロパティを true に設定します。これは、CORS プリフライトリクエストをサポートしようとしていて、HTTP メソッドが options であるためルート述語が true に評価されない場合に役立ちます。

16.2. ルート CORS 構成

「ルート」構成では、キー cors を持つメタデータとして CORS をルートに直接適用できます。グローバル構成の場合と同様に、プロパティは Spring Framework CorsConfiguration (Javadoc) に属します。

ルートに Path 述語が存在しない場合は、'/**' が適用されます。
例 78: application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: cors_route
        uri: https://example.org
        predicates:
        - Path=/service/**
        metadata:
          cors
            allowedOrigins: '*'
            allowedMethods:
              - GET
              - POST
            allowedHeaders: '*'
            maxAge: 30

17. アクチュエーター API

/gateway アクチュエーターエンドポイントを使用すると、Spring Cloud Gateway アプリケーションを監視および操作できます。リモートでアクセスできるようにするには、エンドポイントを有効にして、アプリケーションのプロパティで HTTP または JMX を介して公開する必要があります。次のリストは、その方法を示しています。

例 79: application.properties
management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

このエンドポイントは、子アクチュエーターエンドポイントで利用できるものの概要と、各参照で利用できるメソッドを提供します。結果のレスポンスは次のようになります。

[
   {
      "href":"/actuator/gateway/",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/routedefinitions",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/globalfilters",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/routefilters",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/routes",
      "methods":[ "POST", "GET" ]
   },
   {
      "href":"/actuator/gateway/routepredicates",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/refresh",
      "methods":[ "POST" ]
   },
   {
      "href":"/actuator/gateway/routes/route-id-1/combinedfilters",
      "methods":[ "GET" ]
   },
   {
      "href":"/actuator/gateway/routes/route-id-1",
      "methods":[ "POST", "DELETE", "GET" ]
   }
]

17.1. 詳細なアクチュエーター形式

新しい、より詳細な形式が Spring Cloud Gateway に追加されました。各ルートに詳細が追加され、使用可能な構成とともに、各ルートに関連付けられた述語とフィルターを表示できます。次の例では、/actuator/gateway/routes を構成します。

[
  {
    "predicate": "(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)",
    "route_id": "add_request_header_test",
    "filters": [
      "[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]",
      "[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]",
      "[[PrefixPath prefix = '/httpbin'], order = 2]"
    ],
    "uri": "lb://testservice",
    "order": 0
  }
]

この機能はデフォルトで有効になっています。これを無効にするには、次のプロパティを設定します。

例 80: application.properties
spring.cloud.gateway.actuator.verbose.enabled=false

これは、将来のリリースでデフォルトで true になります。

17.2. ルートフィルターの取得

このセクションでは、以下を含むルートフィルターを取得する方法について詳しく説明します。

17.2.1. グローバルフィルター

すべてのルートに適用されているグローバルフィルターを取得するには、/actuator/gateway/globalfilters に対して GET リクエストを行います。結果のレスポンスは次のようになります。

{
  "org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5": 10100,
  "org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,
  "org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,
  "org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,
  "org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,
  "org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,
  "org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,
  "org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
}

レスポンスには、配置されているグローバルフィルターの詳細が含まれています。各グローバルフィルターには、フィルターオブジェクト (たとえば、org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5) の文字列表現と、フィルターチェーン内の対応する順序があります。

17.2.2. ルートフィルター

ルートに適用された GatewayFilter ファクトリを取得するには、/actuator/gateway/routefilters に対して GET リクエストを行います。結果のレスポンスは次のようになります。

{
  "[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
  "[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
  "[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}

レスポンスには、特定のルートに適用された GatewayFilter ファクトリの詳細が含まれています。ファクトリごとに、対応するオブジェクトの文字列表現があります(たとえば、[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object])。null 値は、エンドポイントコントローラーの実装が不完全であることが原因であることに注意してください。これは、GatewayFilter ファクトリオブジェクトには適用されないフィルターチェーンでオブジェクトの順序を設定しようとするためです。

17.3. ルートキャッシュのリフレッシュ

ルートキャッシュをクリアするには、/actuator/gateway/refresh に POST リクエストを送信します。リクエストは、レスポンス本文なしで 200 を返します。

特定のメタデータ値を持つルートをクリアするには、クエリパラメーター metadata を追加して、クリアするルートが一致する必要がある key:value ペアを指定します。非同期リフレッシュ中にエラーが発生した場合、リフレッシュによって既存のルートが変更されることはありません。

POST リクエストを /actuator/gateway/refresh?metadata=group:group-1 に送信すると、group メタデータが group-1 であるルートのみがリフレッシュされます: first_route および third_route

[{
  "route_id": "first_route",
  "route_object": {
    "predicate": "...",
  },
  "metadata": { "group": "group-1" }
},
{
  "route_id": "second_route",
  "route_object": {
    "predicate": "...",
  },
  "metadata": { "group": "group-2" }
},
{
  "route_id": "third_route",
  "route_object": {
    "predicate": "...",
  },
  "metadata": { "group": "group-1" }
}]

17.4. ゲートウェイで定義されたルートの取得

ゲートウェイで定義されたルートを取得するには、/actuator/gateway/routes に対して GET リクエストを行います。結果のレスポンスは次のようになります。

[{
  "route_id": "first_route",
  "route_object": {
    "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d",
    "filters": [
      "OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"
    ]
  },
  "order": 0
},
{
  "route_id": "second_route",
  "route_object": {
    "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
    "filters": []
  },
  "order": 0
}]

レスポンスには、ゲートウェイで定義されているすべてのルートの詳細が含まれています。次の表に、レスポンスの各要素(それぞれがルート)の構造を示します。

パス タイプ 説明

route_id

String

ルート ID。

route_object.predicate

オブジェクト

ルート述語。

route_object.filters

配列

ルートに適用された GatewayFilter ファクトリ

order

番号

ルートの順序。

17.5. 特定のルートに関する情報の取得

単一のルートに関する情報を取得するには、/actuator/gateway/routes/{id} に対して GET リクエストを行います(たとえば、/actuator/gateway/routes/first_route)。結果のレスポンスは次のようになります。

{
  "id": "first_route",
  "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/first"}
  }],
  "filters": [],
  "uri": "https://www.uri-destination.org",
  "order": 0
}

次の表に、レスポンスの構造を示します。

パス タイプ 説明

id

String

ルート ID。

predicates

配列

ルート述語のコレクション。各項目は、特定の述語の名前と引数を定義します。

filters

配列

ルートに適用されるフィルターのコレクション。

uri

String

ルートの宛先 URI。

order

番号

ルートの順序。

17.6. 特定のルート定義の作成と削除

ルート定義を作成するには、ルートのフィールドを指定する JSON 本文を使用して /gateway/routes/{id_route_to_create} への POST リクエストを行います ( 特定のルートに関する情報の取得を参照)。

ルート定義を削除するには、DELETE リクエストを /gateway/routes/{id_route_to_delete} に送信します。

17.7. 複数のルート定義の作成

単一のリクエストで複数のルート定義を作成するには、ルート ID を含むルートのフィールドを指定する JSON 本文を使用して POST リクエストを /gateway/routes に作成します ( 特定のルートに関する情報の取得を参照)。

ルートの作成中にルートでエラーが発生した場合、ルート定義は破棄されます。

17.8. 要約: すべてのエンドポイントのリスト

次の表は、Spring Cloud Gateway アクチュエーターエンドポイントをまとめたものです (各エンドポイントにはベースパスとして /actuator/gateway があることに注意してください)。

IDHTTP メソッド 説明

globalfilters

GET

ルートに適用されているグローバルフィルターのリストを表示します。

routefilters

GET

特定のルートに適用されている GatewayFilter ファクトリのリストを表示します。

refresh

POST

ルートキャッシュをクリアします。

routes

GET

ゲートウェイで定義されているルートのリストを表示します。

routes/{id}

GET

特定のルートに関する情報を表示します。

routes/{id}

POST

ゲートウェイに新しいルートを追加します。

routes/{id}

DELETE

ゲートウェイから既存のルートを削除します。

17.9. 複数のゲートウェイインスタンス間でルートを共有する

Spring Cloud Gateway は、2 つの RouteDefinitionRepository 実装を提供します。1 つ目は、1 つのゲートウェイインスタンスのメモリ内にのみ存在する InMemoryRouteDefinitionRepository です。この型のリポジトリは、複数のゲートウェイインスタンスにまたがるルートを設定するのには適していません。

Spring Cloud Gateway インスタンスのクラスター間でルートを共有するために、RedisRouteDefinitionRepository を使用できます。この種のリポジトリを有効にするには、次のプロパティを true に設定する必要があります。spring.cloud.gateway.redis-route-definition-repository.enabled RedisRateLimiter Filter Factory と同様に、spring-boot-starter-data-redis-reactive Spring Boot スターターを使用する必要があります。

18. トラブルシューティング

このセクションでは、Spring Cloud Gateway を使用するときに発生する可能性のある一般的な問題について説明します。

18.1. ログレベル

次のロガーには、DEBUG および TRACE レベルの貴重なトラブルシューティング情報が含まれている場合があります。

  • org.springframework.cloud.gateway

  • org.springframework.http.server.reactive

  • org.springframework.web.reactive

  • org.springframework.boot.autoconfigure.web

  • reactor.netty

  • redisratelimiter

18.2. 盗聴

Reactor Netty HttpClient および HttpServer では、盗聴を有効にすることができます。reactor.netty ログレベルを DEBUG または TRACE に設定することと組み合わせると、ネットワークを介して送受信されるヘッダーや本文などの情報のログ記録が可能になります。盗聴を有効にするには、HttpServer と HttpClient にそれぞれ spring.cloud.gateway.httpserver.wiretap=true または spring.cloud.gateway.httpclient.wiretap=true を設定します。

19. 開発者ガイド

これらは、ゲートウェイのいくつかのカスタムコンポーネントを作成するための基本的なガイドです。

19.1. カスタムルート述語ファクトリの作成

ルート述語を作成するには、RoutePredicateFactory を Bean として実装する必要があります。拡張可能な AbstractRoutePredicateFactory と呼ばれる抽象クラスがあります。

MyRoutePredicateFactory.java
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

    public MyRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //grab the request
            ServerHttpRequest request = exchange.getRequest();
            //take information from the request to see if it
            //matches configuration.
            return matches(config, request);
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

19.2. カスタム GatewayFilter ファクトリの作成

GatewayFilter を作成するには、GatewayFilterFactory を Bean として実装する必要があります。AbstractGatewayFilterFactory と呼ばれる抽象クラスを継承できます。次の例は、その方法を示しています。

例 81: PreGatewayFilterFactory.java
@Component
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(builder.build()).build());
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}
PostGatewayFilterFactory.java
@Component
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                //Manipulate the response in some way
            }));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

19.2.1. 構成でのカスタムフィルターと参照の命名

カスタムフィルターのクラス名は GatewayFilterFactory で終わる必要があります。

例: 構成ファイルで Something という名前のフィルターを参照するには、フィルターが SomethingGatewayFilterFactory という名前のクラスに含まれている必要があります。

class AnotherThing など、GatewayFilterFactory サフィックスなしで名前が付けられたゲートウェイフィルターを作成することができます。このフィルターは、構成ファイルで AnotherThing として参照できます。これはサポートされている命名規則ではなく、この構文は将来のリリースで削除される可能性があります。準拠するようにフィルター名を更新してください。

19.3. カスタムグローバルフィルターの作成

カスタムグローバルフィルターを作成するには、GlobalFilter インターフェースを Bean として実装する必要があります。これにより、すべてのリクエストにフィルターが適用されます。

次の例は、グローバルなプレフィルターとポストフィルターをそれぞれ設定する方法を示しています。

@Bean
public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //adds header to proxied request
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds header to response
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}

20. Spring MVC または Webflux を使用した単純なゲートウェイの構築

次に、代替スタイルのゲートウェイについて説明します。以前のドキュメントはいずれも、以下には適用されません。

Spring Cloud Gateway は、ProxyExchange と呼ばれるユーティリティオブジェクトを提供します。通常の Spring Web ハンドラー内でメソッドパラメーターとして使用できます。HTTP 動詞をミラーリングするメソッドを介した基本的なダウンストリーム HTTP 交換をサポートします。MVC では、forward() メソッドを介したローカルハンドラーへの転送もサポートしています。ProxyExchange を使用するには、クラスパスに適切なモジュール(spring-cloud-gateway-mvc または spring-cloud-gateway-webflux のいずれか)を含めます。

次の MVC の例は、リモートサーバーへのダウンストリームの /test へのリクエストをプロキシします。

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

次の例は、Webflux で同じことを行います。

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

ProxyExchange のコンビニエンスメソッドを使用すると、ハンドラーメソッドは受信リクエストの URI パスを検出して拡張できます。例: パスの末尾の要素を抽出して、ダウンストリームに渡すことができます。

@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
  String path = proxy.path("/proxy/path/");
  return proxy.uri(home.toString() + "/foos/" + path).get();
}

Spring MVC と Webflux のすべての機能は、ゲートウェイハンドラーメソッドで使用できます。その結果、たとえば、リクエストヘッダーとクエリパラメーターを挿入したり、マッピングアノテーションの宣言で受信リクエストを制限したりできます。これらの機能の詳細については、Spring MVC の @RequestMapping のドキュメントを参照してください。

ProxyExchange で header() メソッドを使用して、ダウンストリームレスポンスにヘッダーを追加できます。

マッパーを get() メソッド(およびその他のメソッド)に追加することで、レスポンスヘッダー(およびレスポンス内で好きなもの)を操作することもできます。マッパーは、受信 ResponseEntity を取得して発信 ResponseEntity に変換する Function です。

ファーストクラスのサポートは、ダウンストリームに渡されない「機密」ヘッダー(デフォルトでは cookie および authorization)、および「プロキシ」(x-forwarded-*)ヘッダーに対して提供されます。

21. AOT およびネイティブイメージのサポート

4.0.0 以降、Spring Cloud Gateway は Spring AOT 変換とネイティブイメージをサポートします。

負荷分散ルートを使用している場合は、LoadBalancerClient サービス ID を明示的に定義する必要があります。これは、@LoadBalancerClient アノテーションの value または name 属性を使用するか、spring.cloud.loadbalancer.eager-load.clients プロパティの値として使用することで実行できます。

22. 構成プロパティ

Spring Cloud Gateway に関連するすべての構成プロパティのリストを表示するには、付録を参照してください。