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