Spring MVC または Webflux を使用したプロキシ交換ゲートウェイ

以下に、代替スタイルのゲートウェイについて説明します。Spring Cloud Gateway サーバーのドキュメントは、以下の内容には適用されません。

Spring Cloud Gateway プロキシ交換を含める方法

Spring Cloud Gateway プロキシ交換をプロジェクトに含めるには、MVC プロキシ交換のグループ ID が org.springframework.cloud で、アーティファクト ID が spring-cloud-gateway-mvc のアーティファクトを使用します。WebFlux プロキシ交換の場合は、グループ ID が org.springframework.cloud で、アーティファクト ID が spring-cloud-gateway-webflux のアーティファクトを使用します。

現在の Spring Cloud リリーストレインを使用したビルドシステムのセットアップの詳細については、Spring Cloud プロジェクトページを参照してください。

プロキシ交換の使用

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) と「スキップ」ヘッダー (デフォルトでは content-length と host)、および「プロキシ」(x-forwarded-*) ヘッダーに対して、ファーストクラスのサポートが提供されます。「スキップ」ヘッダーの背景となる考え方は、下流のリクエストにコピーされたときに問題が発生する可能性があるということです。たとえば、ProxyExchange が下流のエンドポイントを呼び出す方法が原因で、コンテンツの長さが変更されたり、Content-Length ヘッダーの代わりに Transfer-Encoding: chunked が使用されたりする可能性があります。