Don't Repeat Yourself (DRY) はソフトウェア開発における重要な原則です。この記事では、これを Apache APISIX 構成に適用する方法を説明します。 DRY原則 「Don't repeat yourself (DRY)」は、変更される可能性のある情報の繰り返しを減らし、変更される可能性が低い抽象化に置き換えたり、そもそも冗長性を回避するデータ正規化を使用することを目的としたソフトウェア開発の原則です。 -- Wikipedia - 同じことを繰り返さないでください DRY の背後にある主な考え方は、同じことを繰り返して情報が変更された場合、変更された情報を複数の場所で更新する必要があるということです。これは余分な労力がかかるだけでなく、それを忘れて、場所によって異なる情報が存在する可能性もあります。DRY はバグ修正で効果を発揮します。 バグを含むコード スニペットを想像してください。そして、そのスニペットを 2 つの異なる場所に複製したと想像してください。次に、この 2 か所のバグを修正する必要がありますが、これは簡単な部分です。難しいのは、そもそも複製について知ることです。 複製する人と修正する人は異なる可能性が高いです。スニペットが共有可能にリファクタリングされ、代わりに 2 つの場所から呼び出される場合は、この 1 か所のバグを修正するだけで済みます。 ほとんどの人は、DRY をコードと関連付けます。ただし、DRY はより制限的であり、本来の考え方に反する可能性があります。 この原則は、Andy Hunt 氏と Dave Thomas 氏が著書「The Pragmatic Programmer」でまとめたものです。彼らはこれを、データベース スキーマ、テスト プラン、ビルド システム、さらにはドキュメントまで、かなり広範囲に適用しています。 -- Wikipedia - 同じことを繰り返さないでください 健全な構成システムは DRY を許可し、さらにはそれを奨励します。 Apache APISIX の DRY Apache APISIX は 2 か所で DRY 構成を提供します。 DRY アップストリーム 電子商取引のコンテキストでは、Apache APISIX でルートを定義するための初心者の旅は、おそらく次のように始まります。 routes: - id: 1 name: Catalog uri: /products* upstream: nodes: "catalog:8080": 1 APISIX に詳しい方ならご存知かと思いますが、 URI の下にカタログへのルートを定義しました。ただし、問題があります。おそらく、潜在的な顧客にカタログを閲覧してもらいたいが、製品の作成、削除、更新は禁止したいと考えるでしょう。しかし、デフォルトでは、ルートはすべての HTTP メソッドと一致します。 /products 誰もがカタログを自由に閲覧できるように、認証されたユーザーのみがカタログを管理できるようにする必要があります。このアプローチを実装するには、ルートを 2 つに分割する必要があります。 routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] #1 uri: /products* upstream: #2 nodes: "catalog:8080": 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] #3 uri: /products* plugins: key-auth: ~ #4 upstream: #2 nodes: "catalog:8080": 1 マッチブラウジング アップストリームに重複しました! 試合管理 認証された消費者だけがこのルートを使用できます。key 、このための最もシンプルなプラグインです。 key-auth 私たちは、コピー アンド ペーストという可能な限り簡単な方法でセキュリティの問題を修正しました。これにより、 セクションが複製されました。ノードの追加や削除 、トポロジを変更する必要がある場合は、2 か所で変更する必要があります。これは DRY 原則に反します。 upstream など 実際のシナリオでは、特にコンテナが関係する場合は、 をリストすることで を実装することはありません。代わりに、トポロジの変更に対応するために動的な を実装する必要があります。ただし、サービス検出の構成または実装を変更する必要がある場合、この点は依然として有効です。したがって、私のポイントはノードとサービス検出に等しく当てはまります。 nodes upstream サービス検出 抽象化に加えて、APISIX は DRY を実装するための 抽象化を提供します。上記のスニペットを次のように書き直すことができます。 Route Upstream upstreams: - id: 1 #1 name: Catalog nodes: "catalog:8080": 1 routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /products* upstream_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /products* upstream_id: 1 #2 plugins: key-auth: ~ ID のアップストリームを定義する 1 ルートで参照する トポロジーで何かが起こった場合、単一の でのみ変更を更新する必要があります。 Upstream 埋め込まれた を定義することと、それを で参照することは あることに注意してください。 upstream upstream_id 相互に排他的で DRYプラグインの設定 APISIXが 抽象化によって設定をDRYにするのに役立つもう1つの領域。APISIXは、すべてではないにしても、ほとんどの機能をプラグインを通じて実装します。 プラグインの API に を実装しましょう。転送する前に URL を書き換える必要があります。 パスベースのバージョン管理 routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] #1 転送する前に プレフィックスを削除してください /v1 上記の と同様に、 セクションは重複しています。専用の オブジェクトにプラグイン構成を組み込むこともできます。次のスニペットは、上記と同じ効果があります。 upstream plugins Plugin Config plugin_configs: - id: 1 #1 plugins: proxy-rewrite: regex_uri: [ "/v1(.*)", "$1" ] routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 #2 プラグインの設定を専用オブジェクトにまとめる 参照してください 賢明な読者は、設定の一部が抜けていることに気付いたかもしれません。 不思議なことに消えてしまったのです。実際、わかりやすくするために削除したのです。 auth-key と とは異なり、 と 。不足している を追加するだけで問題を解決できます。 upstream upstream_id plugins plugin_config_id 相互に排他的ではありません plugin routes: - id: 1 name: Read the catalogue methods: [ "GET", "HEAD" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 - id: 1 name: Read the catalogue methods: [ "PUT", "POST", "PATCH", "DELETE" ] uri: /v1/products* upstream_id: 1 plugin_config_id: 1 plugins: key-auth: ~ #1 直して! この方法では、共有設定を オブジェクトに移動し、特定の設定をそれが適用される場所に保持できます。しかし、異なる設定を持つ同じプラグインが と で直接使用されている場合はどうなるでしょうか? には、これについて非常に明確に説明されています。 plugin_config plugin_config route ドキュメント > > > > Consumer Consumer Group Route Plugin Config Service つまり、 内の 設定は の設定よりも優先されます。また、 内の プラグインの 変数を提供し、ルート内でのみそれを設定することもできます。APISIX は各 のキーを見つけて使用します。 route plugin plugin_config_id consumer key-auth apikey consumer 結論 DRY はコードに関することだけではなく、データ管理全般に関することです。構成はデータなので、この一般的な範疇に含まれます。 APISIX は 2 つの DRY オプションを提供します。1 つは 用 - 、もう 1 つは 用 - 。アップストリームは排他的ですが、プラグインは上書きを許可します。 upstream upstream_id plugin plugin_config_id どちらのメカニズムも、構成を DRY 化し、長期的に保守性を高めるのに役立ちます。 さらに進むには: 同じことを繰り返さない原則 構成マージの優先順位 2024年9月1日に で最初に公開されました A Java Geek