表現言語について
バージョン3.0のリリースにより、Kong Gatewayにはドメイン固有の式言語を使用するルールベースのエンジンが含まれるようになりました。式は、3.0より前のルーターでは不可能だった複雑なルーティングロジックの定義など、 タスクを実行するために使用できます。 このガイドは式言語のリファレンスであり、その使用方法について説明します。
式言語について
表現言語は、厳密に型指定されたドメイン固有言語(DSL)です。 これにより、さまざまな入力データに対する比較演算を定義できます。 比較結果は論理演算と組み合わせることができます。これにより、実行時のマッチングパフォーマンスを良好に保ちながら、複雑なルーティングロジックを記述できます。
重要な概念
-
フィールド: フィールドは受信リクエストから抽出された値を含みます。たとえば リクエストパスまたはヘッダーフィールドの値です。フィールド値がない場合も あります。フィールド値が存在しない場合、述部は演算子に関係なく、常に
false
を生成します。フィールドは常に述部の左側に表示されます。 - 定数値: 定数値は、提供された演算子に基づいて、フィールドが比較 されるものです。定数値は常に述部の右側に表示されます。
- 演算子: 演算子は、提供された定数値に対して、フィールドで実行したい比較アクションを定義します。 演算子は常に述部の中間、フィールドと定数値の間に 表示されます。
-
述部: 述部は、提供された演算子とを使用して、フィールドを事前定義された値と比較します。フィールドが比較に 合格した場合は
true
を返し、合格しなかった場合はfalse
を返します。 - ルート: 論理演算子と組み合わせた1つまたは複数の述部です。
- ルーター: ルーターは、受信リクエストと照合してすべて評価されるルートの集まりです。 一致するものが見つかるまで続きます。
- 優先度: ルーターの評価順序を定義する正の整数です。 優先度が高いほどルートの評価順序が早くなります。同じルーター内で2つのルートの優先度が重複する場合、評価順序は定義されません。
述部は、次のように構成されます。
http.path ^= "/foo/bar"
この述部の例は、次の構造に従っています。
-
http.path
:フィールド -
^=
:演算子 -
"/foo/bar"
:定数値
ルートの実行方法
実行時に、Kong GatewayがHTTPおよびストリーム(TCP、TLS、UDP)サブシステム用に2つの個別のルーターを構築します。
適切なpriority
フィールドが設定されたルートが各ルーターに挿入されます。ルーターは
構成されたルートの変更に応じて段階的に更新されます。
リクエスト/接続が入ると、Kong Gatewayは構成したルートに必要なフィールドを調べます。
そして、これらのフィールドの値をルーターの実行コンテキストに提供します。これは構成されたルートに対して
降順で評価されます(priority
番号の大きいルートが最初に評価されます)。
ルートが一致するとすぐに、ルーターはマッチングを停止し、一致したルートを使用して現在のリクエスト/接続を処理します。
図1: Kong Gatewayのルート実行方法の図。この図には、Kong Gatewayが式に一致するルートを選択してから、最高の優先度と一致するルートを選択することが示されています。
式ルーターの例(HTTP)
接頭辞ベースのパスマッチング
接頭辞ベースのパスマッチングは、ルーティングで最も一般的に使用される方法の 1 つです。たとえば、パスが/foo/bar
で始まるHTTPリクエストを一致させたい場合は、次のルートを記述できます。
http.path ^= "/foo/bar"
正規表現ベースのパスマッチング
HTTPリクエストパスを正規表現と照合する場合は、次のルートを記述できます。
http.path ~ r#"/foo/bar/\d+"#
大文字と小文字を区別しないパスの照合
パスマッチングを実行するときに大文字と小文字を区別しない場合は、フィールドにlower()
修飾子を付けると、
常に小文字の値を返すようになります。
lower(http.path) == "/foo/bar"
これは、たとえば、パス/foo/bar
と/FOO/bAr
を持つリクエストと一致します。
ヘッダー値による一致
受信リクエストをヘッダーX-Foo
の値で照合する場合は、次の手順を実行します。
http.headers.x_foo ~ r#"bar\d"#
X-Foo
に複数のヘッダー値があり、クライアントが値が異なる
X-Foo
ヘッダーを1つ以上送信した場合、上の例では次の 各 インスタンスの値が
正規表現r#"bar\d"#
と確実に一致します。これは「全」スタイルマッチングと呼ばれ、フィールド値の各インスタンスが
true
を返すために、述部の比較に合格する必要があります。これはデフォルトの動作です。
この動作を望まない場合は、”any” スタイルのマッチングをオンにすると、
いずれかの値が比較に合格するとすぐ、述語に対してtrue
を返します。
any(http.headers.x_foo) ~ r#"bar\d"#
これは、http.headers.x_foo
の値が正規表現のr#"bar\d"#
と一致するとすぐにtrue
を返します。
さまざまな変換を連結できます。以下も、 大文字と小文字を区別しないマッチングを実行する有効なユースケースです。
any(lower(http.headers.x_foo)) ~ r#"bar\d"#
正規表現キャプチャ
正規表現キャプチャグループは、後でプラグインで利用可能になる任意の
正規表現操作で定義できます。現在のところ、これはhttp.path
フィールドでのみサポートされています。
http.path ~ r#"/foo/(?P<component id="sl-md0000000">.+)"#
component
の一致した値は、
Request Transformer Advancedのようなプラグインで、後から利用できるようになります。
式ルーターの例(TCP、TLS、UDP)
送信元IPと宛先ポートによる一致
net.src.ip in 192.168.1.0/24 && net.dst.port == 8080
上記は192.168.1.0/24
サブネット内のすべてのクライアントを照合します。(Kongがリッスンする)宛先ポートは8080
です。
IPv6アドレスもサポートされます。
SNIによる一致(TLSルートの場合)
tls.sni =^ ".example.com"
これは、.example.com
SNIで終わるすべてのTLS接続に一致します。
詳細情報
- 言語リファレンス - 式ルーターの基本に慣れたら、このドキュメントを参照して、式言語が提供するすべてを理解してください。
- 式を使用してルートを構成する方法。- 式を使用してルートを構成する方法と、使用可能なフィールドをご紹介します。
- パフォーマンス - 式ルーターを使う場合のパフォーマンス特性と、 ルートを最適化する方法について理解してください。
- 式リポジトリ