探索 APIM 原則

已完成

在 Azure APIM 管理中,原則可讓發行者透過設定變更 API 的行為。 原則是「陳述式」的集合,會在 API 的要求或回應上循序執行。

原則是在位於 API 取用者與受控 API 之間的網路閘道內套用。 網路閘道會接收所有要求,然後通常原封不動地轉送至基礎 API。 不過,原則可以套用至輸入要求和輸出要求。 如果原則不另行指定,則可以在任何 APIM 原則中,使用原則運算式做為屬性值或文字值。

了解原則設定

原則定義是一份簡單的 XML 文件,描述一連串輸入和輸出陳述式。 可直接在定義視窗中編輯 XML。

設定分為 inboundbackendoutboundon-error。 系統會針對要求和回應而依序執行一連串指定原則陳述式。

<policies>
  <inbound>
    <!-- statements to be applied to the request go here -->
  </inbound>
  <backend>
    <!-- statements to be applied before the request is forwarded to 
         the backend service go here -->
  </backend>
  <outbound>
    <!-- statements to be applied to the response go here -->
  </outbound>
  <on-error>
    <!-- statements to be applied if there is an error condition go here -->
  </on-error>
</policies>

若在處理要求期間發生錯誤,便會略過 inboundbackendoutbound 區段中的所有剩餘步驟,且執行程序會跳至 on-error 區段中的陳述式。 將原則陳述式置於 on-error 區段中,您即可使用 context.LastError 屬性檢閱錯誤、使用 set-body 原則檢查和自訂錯誤回應,以及設定錯誤發生時採取的動作。

原則運算式

如果原則不另行指定,則可以在任何 APIM 原則中,使用原則運算式作為屬性值或文字值。 原則運算式可以是:

  • @(expression) 括住的單一 C# 陳述式,或
  • 括住在 @{expression} 中,並會傳回值的多陳述式 C# 程式碼區塊

每個運算式具有存取權以隱含方式提供 context 變數並允許子集的 .NET Framework 型別。

原則運算式提供複雜的方法來控制流量和修改 API 行為,您無須撰寫特製化程式碼或修改後端服務。

下列範例會使用原則運算式和 set-header 原則,將使用者資料新增至傳入要求。 新增的標頭包含與要求中訂用帳戶金鑰相關聯的使用者識別碼,以及處理要求之網路閘道託管的區域。

<policies>
    <inbound>
        <base />
        <set-header name="x-request-context-data" exists-action="override">
            <value>@(context.User.Id)</value>
            <value>@(context.Deployment.Region)</value>
      </set-header>
    </inbound>
</policies>

套用在不同範圍指定的原則

若您在全域層級中有一個原則,還有一個為 API 設定的原則,則每次使用該特定 API 時,皆會套用這兩個原則。 APIM 可透過 base 元素來指定組合式原則陳述式的固定順序。

<policies>
    <inbound>
        <cross-domain />
        <base />
        <find-and-replace from="xyz" to="abc" />
    </inbound>
</policies>

在上述範例原則定義中,系統會先執行 cross-domain 陳述式。 find-and-replace 原則會在範圍較廣的任何原則之後執行。

篩選回應內容

以下範例中定義的原則示範如何根據要求的關聯產品,篩選回應承載中的資料元素。

程式碼片段假設回應內容的格式為 JSON,並包含名為 「minutely」、「hourly」、「daily」、「flags」 的根層級屬性。

<policies>
  <inbound>
    <base />
  </inbound>
  <backend>
    <base />
  </backend>
  <outbound>
    <base />
    <choose>
      <when condition="@(context.Response.StatusCode == 200 && context.Product.Name.Equals("Starter"))">
        <!-- NOTE that we are not using preserveContent=true when deserializing response body stream into a JSON object since we don't intend to access it again. See details on /azure/api-management/api-management-transformation-policies#SetBody -->
        <set-body>
          @{
            var response = context.Response.Body.As<JObject>();
            foreach (var key in new [] {"minutely", "hourly", "daily", "flags"}) {
            response.Property (key).Remove ();
           }
          return response.ToString();
          }
    </set-body>
      </when>
    </choose>    
  </outbound>
  <on-error>
    <base />
  </on-error>
</policies>