APIMポリシーの適用順序

Pocket

APIMポリシーの適用順序

はじめに

  • Azure API Management における重要な概念として ポリシー があります
  • ポリシーを定義することで、APIに対するアクセスを制御したり、あるいは加工したりなどといったことも可能です
  • 応用の幅が非常に広いポリシーですが、基本的な部分で思わぬ誤動作を招くこともあります
    • 今回はその中でもシンプルにして頭を悩ます「ポリシーの適用順序」について簡単にご説明します。

ポリシーを定義する場所(スコープ)

API Management では、以下の単位でポリシーを定義できます。

  • グローバル
  • 製品(最近だと「成果物」と呼ばれる?)
  • API
  • オペレーション(「操作」とも)

それぞれには以下のようにXMLライクな形式でポリシーを定義します。

<policies>
    <inbound>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

上記 inbound, backend, outbound, on-error といったくくりがありますが、
これは簡単に言うと クライアントリクエスト受信時, バックエンドにリクエストを送る直前, バックエンドからリクエストが帰ってきた直後(クライアントにレスポンスを返す直前), エラー時 それぞれのタイミングでの処理を定義するためのものです(今回は inbound のみでお話します)

今回の肝となるのは、上記ポリシーに出てくる <base /> です。

ポリシーの適用順序

ポリシーの4つのスコープをご紹介しましたが、そのスコープには適用順序があります。

Azureの公式ドキュメントでは以下の順で適用されると記載されています。
Azure API Management ポリシーの設定または編集方法 – スコープの構成

  1. グローバル
  2. 製品(成果物)
  3. API
  4. オペレーション(操作)

実際に確かめるには、簡単に以下のようなポリシーを組んでみるとわかりやすいです。

    <inbound>
        <base />
        <return-response>
            <set-status code="200" reason="ok" />
            <set-body />
        </return-response>
    </inbound>

inboud のみ抜き出して記載

このポリシーをグローバル/製品/API/オペレーションに貼り、
その際に code を 201, 202・・・ のようにそれぞれ変えれば、レスポンスコードによってどのような順番でポリシーが適用されているかがわかります。
例えば以下のように設定します。

  1. グローバルには code="200"
  2. 製品には code="201"
  3. APIには code="202"
  4. オペレーションには code="203"

上記の状態で、API(オペレーション)を叩くと グローバルのポリシーが優先的に適用されるため、レスポンスは 200 となります。そしてグローバルポリシーをコメントアウトすれば 201 が、グローバルと製品ポリシーをコメントアウトすれば 202 が返ってきますので、上記の順番でポリシーが適用されていることがわかります。

base とは

さて、ここまで説明していなかった <base /> というポリシーがありますが、
これは 親のポリシーを呼び出す役割 があります。

先程実験をして確かめた以下の順番において

  1. グローバル
  2. 製品(成果物)
  3. API
  4. オペレーション(操作)

例えば オペレーションポリシーに定義された <base /> は、APIポリシーを呼び出すことができます。
APIポリシーで更に <base /> を定義していれば、製品ポリシーを呼び出すことができます。
上記順番の下から上にさかのぼっていくことができるイメージです。

base の位置

という事は、さかのぼっていくことを止めることもできる訳です。
以下のようなポリシーを「オペレーション」に定義してみます。

    <inbound>
        <return-response>
            <set-status code="203" reason="ok" />
            <set-body />
        </return-response>
        <base />
    </inbound>

※ グローバルには 200 を返すように設定済みとします

先程とほぼ変わっていないように思えますが <base /> ポリシーの位置が変わっています(return-response の後になっています)
この状態でAPI(オペレーション)を叩いてみると 203 が返ってきます。

これはつまり <base /> が呼び出される前に 203レスポンスを返しているということです。

仮に、すべて <base /> の位置を、上記のように 「後」 に変えた場合のポリシーの適用順序は、以下のように 真逆 となります。

  1. オペレーション(操作)
  2. API
  3. 製品(成果物)
  4. グローバル

base の落とし穴

  • <base /> というポリシーを正しく理解していれば、当たり前の挙動・・・といったような気がします
  • が、実運用などで <base /> ポリシーの前後 にまで気が回らず、思わぬ誤動作 ・・・ということは意外とあります。。
    • たった一行の <base /> が 前にあるか後ろにあるか だけで動作が変わるため、意外と見落としてしまいます…。
    • すぐに誤動作に気付ければ幸いですが、誤動作かどうか分かりづらい場合などもあるので、検証は慎重に行ったほうが良いです。
  • ポリシーを書いた後の動作確認方法としては・・・
    • トレースログを活用し、どのような順番でポリシーが適用されているかを調べる
    • 最近だと デバッグポリシーというものも充実している(らしい)ので、こちらも使ってみる・・・など

まとめ

  • <base /> ポリシーの意味を理解しましょう
    • 非常にシンプルですが、自身でポリシーを書きながら試行することをオススメします
  • <base /> がポリシーのどの位置にあるのかで、ポリシーの適用順序は変わってしまいます
    • つまり動作が大きく異なるため、検証は慎重に行いましょう!
Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です