Docker java Spring 未分類

Spring Cloud Gatewayでリクエストボディーのカスタムpredicate(ルーティング)

投稿日:

はじめに

アプリケーションレイヤーでオリジナルなルールでルーティングするプロキシが欲しい際にSpring Cloud Gatewayは非常に便利です。

プロキシを検討する際に、例えばAWSではCloudFrontやALBが候補として上がりますし、コンテナでプロキシを経由させるのであればEnvoyやNginxが候補として上がりますが、いずれもオリジナルなルールを作成するには限界があったり、少し骨が折れます。(と調べて理解しました)

Spring Cloud Gatewayを利用すれば、(Springを知っている人なら)簡単にオリジナルなルールを作成でき、非常に便利です。

ただし、Spring WebFlux上に構築されているため、通常のSpring MVCとは様相が違います。特にServerWebExchangeに頭を悩ませることでしょう。

中でもリクエストボディについては沼る部分(私は沼りました)なので、リクエストボディの中身を確認してルーティングするルール(predicate)を作成するサンプルを作成しました。

サンプルコード

githubへサンプルを上げてますので、参考にいただければ幸いです。

サンプルコードではリクエストボディが”target-request-body”とう文字列であれば”http://localhost:50080″へルーティングし、それ以外は”http://localhost:60080″へルーティングします。

ちなみに、以下の記事がdocker-composeで50080と60080でFlaskを上げるサンプルを紹介しているので、併せて参考にいただけると幸いです。

何すれば良い

predicateを作成する

オリジナルのpredicateを作成する方法についてはbaeldungの記事を参照してください。わかりやすいです。

リクエストボディを取り回したい場合はServerWebExchangeから”cachedRequestBodyObject”の属性値を取得することでリクエストボデイを取得できます。

サンプルでは以下の部分です。

routesの定義をapplication.ymlからJavaへ変更してReadBodyPredicateFactoryを含める

requestBodyを利用したpredicateを作成するにはReadBodyPredicateFactoryを利用する必要がありますが、application.ymlでは利用できません。

application.ymlでルーティングを定義している場合はjavaに移行した上で、対象とするroutesの定義にReadBodyPredicateFactoryのpredicateを追加する必要があります。

ちなみに、GETリクエストの場合はリクエストボディが含まれないためReadBodyPredicateFactoryでFalseになってしまいます。可読性向上と意図しない動作を防ぐためにもmethodのpredicateを入れておくことを強くお勧めします。

サンプルでは以下のようにjavaの@Configurationで定義してます。

参考:
https://github.com/spring-cloud/spring-cloud-gateway/issues/690
https://github.com/spring-cloud/spring-cloud-gateway/issues/152

-Docker, java, Spring, 未分類

Copyright© 若手SIerサラリーマンの独学メモ , 2022 All Rights Reserved Powered by STINGER.