含有流程變數的條件

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

條件陳述式是所有程式設計語言中常見的控制結構。如同程式設計語言,API Proxy 設定也支援資料流、政策、步驟和 RouteRules 的條件陳述式。藉由定義條件陳述式,您可以定義 API 的動態行為。這項動態行為可讓您執行多項操作,例如將行動裝置的 XML 轉換為 JSON,或根據要求訊息的內容類型或 HTTP 動詞轉送至後端網址。

本主題說明如何使用條件,在執行階段動態套用 API 管理功能,而不必編寫任何程式碼。

設定條件陳述式

透過使用conditionsconditions的組合,即可在 API Proxy 中實作條件式行為。系統會使用 Condition 元素建立條件陳述式。以下為空白條件:

<Condition></Condition>

如要建立條件陳述式,請新增條件運算子和變數,以便建立以下結構:

<Condition>{variable.name}{operator}{"value"}</Condition>

支援的條件運算子包括 = (等於)、!= (不等於) 和 > (大於)。為了方便閱讀,您也可以將條件式寫成文字:equalsnotequalsgreaterthan

使用 URI 路徑時,您可以使用 ~/MatchesPath。您也可以使用 ~~ 運算子比對 JavaRegex 規則運算式。

條件可用來定義後端 API 資源的 API Proxy 條件式流程,如「建立前往後端 API 資源的條件式流程」一文所述。如需完整的條件清單,請參閱條件參考資料

變數

條件的作用是評估變數的值。變數是由 API Proxy 執行的 HTTP 交易屬性,或 API Proxy 設定本身的屬性。每當 API Proxy 從應用程式收到要求時,Apigee Edge 會填入與系統時間、應用程式網路資訊、訊息的 HTTP 標頭、API Proxy 設定、政策執行作業等項目相關的長變數清單。這樣就能建立豐富的結構定義,方便您設定條件陳述式。

變數一律使用點號標記法。舉例來說,要求訊息中的 HTTP 標頭可做為名為 request.header.{header_name} 的變數使用。因此,如要評估 Content-type 標頭,您可以使用變數 request.header.Content-type。例如 request.header.Content-type = "application/json" 表示要求的內容類型應為 JSON。

假設您需要建立條件陳述式,設定只有在要求訊息為 GET 時,系統才會強制執行政策。如要建立條件來評估要求的 HTTP 動詞,請在下方建立條件陳述式。這個條件中的變數為 request.verb。這個變數的值是 GET。運算子為 =

<Condition>request.verb = "GET"</Condition>
你也可以使用:
<Condition>request.verb equals "GET"</Condition>

Edge 會使用這類陳述式來評估條件。如果與要求相關聯的 HTTP 動詞為 GET,上述範例會評估為 True。如果與要求相關聯的 HTTP 動詞是 POST,則陳述式會評估為 false。

如要啟用動態行為,您可以將「條件」附加至流程、步驟和轉送規則。

當您將條件附加至流程時,即可建立「條件式流程」。條件式流程只會在條件評估結果為 True 時執行。您可以為條件式流程附加任意數量的政策。條件式流程可讓您針對符合特定條件的要求或回應訊息,建立高度專業的處理規則。

例如,若要建立僅在要求動詞為 GET 時執行的流程:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

如要為 GET 和 POST 建立另一個 Flow:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
  <Flow name="ExecuteForPOSTs">
  <Condition>request.verb="POST"</Condition>
  </Flow>
</Flows>

如以下範例所示,您可以將條件套用至政策步驟。下列條件會導致只有在要求訊息為 POST 時強制執行 VerifyApiKey 政策。

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

定義這類條件式流程後,您可以將政策附加至這類流程,讓 API Proxy 對 GET 要求強制執行一組政策,並為 POST 要求強制執行另一組政策。

如需完整的參考資訊,請參閱下列資源:

範例 1

以下範例顯示名為 Convert-for-devices 的單一條件式流程,並於 ProxyEndpoint 回應流程中設定。將條件做為元素新增至要套用條件的實體。在這個範例中,條件是資料流的元件。因此,每當陳述式評估為 true 時,系統就會執行資料流。

<Flows>
  <Flow name="Convert-for-devices">
  <Condition>(request.header.User-Agent = "Mozilla")</Condition>
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

對於從應用程式收到的每個要求,Edge 會將所有 HTTP 標頭的值儲存為變數。如果要求包含名為 User-Agent 的 HTTP 標頭,該標頭及其值會儲存為 request.header.User-Agent 變數。

根據上述的 ProxyEndpoint 設定,Edge 會檢查 request.header.User-Agent 變數的值,確認條件是否為 true。

如果條件評估結果為 True,也就是變數 request.header.User-Agent 的值等於 Mozilla,系統就會執行條件式流程,並強制執行名為 ConvertToJSON 的 XMLtoJSON 政策。否則,系統不會執行 Flow,並將未修改的 XML 回應 (以 XML 格式) 傳回給提出要求的應用程式。

範例 2

我們使用一個特定範例,您會需要將回應訊息從 XML 轉換為 JSON (但僅限行動裝置)。首先,請建立政策,將 Weather API 中的 XML 格式回應轉換為 JSON:

<XMLToJSON name="ConvertToJSON">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

上述政策設定會指示 API Proxy 接收回應訊息、使用預設設定執行從 XML 轉換為 JSON 作業,然後將結果寫入新的回應訊息。(如果您要將 request 訊息從 XML 轉換為 JSON,只需將這兩個值設為 request 即可)。

由於您想將回應從 XML 轉換為 JSON,因此必須設定條件式回應流程來執行轉換作業。舉例來說,如要先將所有回應從 XML 轉換為 JSON,再傳回用戶端應用程式,請設定下列 ProxyEndpoint 回應流程。

<Flows>
  <Flow name="Convert-for-devices">
    <Response>
      <Step><Name>ConvertToJSON</Name></Step>
    </Response>
  </Flow>
</Flows>

使用標準要求叫用 API 時,回應會以 JSON 格式顯示。

不過,您的目標是只有在要求用戶端為行動裝置時,才會將天氣報表轉換為 JSON。如要啟用這類動態行為,您必須在 Flow 中新增條件陳述式。

測試條件式流程

在這個範例要求中,HTTP User-Agent 標頭設為 Mozilla,導致條件陳述式評估結果為 true,並執行條件流程 Convert-for-devices

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

在支援 Python 的地方,或是 編寫方便列印的內容:

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool

回應範例:

. . .

"yweather_forecast": [
         {
              "code": "11",
              "date": "12 Dec 2012",
              "day": "Wed",
              "high": "55",
              "low": "36",
              "text": "Showers"
          },
          {
              "code": "32",
              "date": "13 Dec 2012",
              "day": "Thu",
              "high": "56",
              "low": "38",
              "text": "Sunny"
          }
      ]
  }

. . .

如果提交要求時沒有 User-Agent 標頭,或是與 Mozilla 的值不同,就會產生 XML 格式的回應。

$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

系統會傳回未修改的 XML 回應。

回應範例:

<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />

模式比對

本節說明如何在 Apigee 流程中使用模式比對和條件。

運算子

本節說明如何在條件陳述式中使用下列模式比對運算子:

相符

先查看「相符」或「~」條件運算子。這兩個運算子相同,系統會將英文版本「符合」視為更容易判讀的選項。

摘要:「符合項目」運算子會為您提供兩種可能性。您可以用常值比對字串,也可以用「*」進行萬用字元比對。正如預期,萬用字元會比對零個或多個字元。接下來是運作方式範例

下列 XML 顯示步驟條件。當條件評估為 True 時,這個函式就會執行 somePolicy 政策。在此範例中,我們會測試變數 proxy.pathsuffix,這是 Edge 中的內建變數,用於儲存要求的路徑後置字串。請注意,您可以測試任何包含字串的流程變數值。因此,在本範例中,如果傳入要求的基本路徑為 /animals,且要求是 /animals/cat,則路徑後置字串為常值字串「/cat」。

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix Matches "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

問題:哪些 Proxy 路徑後置字串會導致系統在部分政策執行?只有一個可能。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?是,因為 Proxy 路徑後置字串與「/cat」完全相符。如果後置字串是 /bat/dog、「/」或任何其他,就不會執行。

現在,請考慮使用萬用字元「*」的條件陳述式:

<Condition>(proxy.pathsuffix Matches "/*at")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?是,因為萬用字元會與任何字元相符,而 "/cat 即為比對項目。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/bat

政策是否會執行?是,因為萬用字元與任何字元相符,因此 "/bat" 即為比對項目。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/owl

政策是否會執行?簡言之,雖然萬用字元與「o」相符,但系統卻比對字母「wl」。

現在,我們將萬用字元移至後置字串結尾:

<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?是,因為萬用字元符合零或多個字元。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/bat

政策是否會執行?否,「/bat」不相符。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat123

政策是否會執行?是的,萬用字元會比對零個或多個字元,因此「123」會產生比對。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse

政策是否會執行?是,因為萬用字元會與零或多個字元比對,因此「/bird/mouse」會產生比對。請注意,這類運算式會如何比對常值字元之後的所有內容,因而產生問題!

問題:比對運算子是否區分大小寫?

可以,假設您設定的條件如下:

<Condition>(proxy.pathsuffix Matches "/*At")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?否,萬用字元會與任何字母比對 (不論大小寫),但小寫的「a」與「A」不相符。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/bAt

政策是否會執行?是,大小寫相符。

問題:如何使用比對運算子逸出字元?

請使用百分比「%」字元逸出保留字元。例如:

<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?否,「match」運算子會尋找常值字串「c*at」。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/c*at

問題:政策是否會執行?

是,但這個路徑有點不尋常的比對。

JavaRegex

如您所見,「符合」運算子適用於簡單的情況。不過,您可以使用其他運算子,也就是「JavaRegex」或「~~」運算子。這兩個運算子相同,但 JavaRegex 更容易讀取。之所以稱為 JavaRegex,是因為它允許規則運算式模式比對,而 Edge 遵循與 Java 語言 java.util.regex 套件中的類別相同的規則。JavaRegex 運算子的運作方式與比對運算子大不相同,因此千萬不要混淆兩者!

摘要:「JavaRegex」運算子可讓您在條件陳述式中使用規則運算式語法。

下列程式碼顯示步驟條件。如果條件評估結果為 True,就會執行 somePolicy 政策。在此範例中,我們會測試變數 proxy.pathsuffix,這是 Edge 中的內建變數,可儲存要求的路徑後置字串。如果傳入要求的基本路徑為 /animals,且要求是 /animals/cat,則路徑後置字串為常值字串「/cat」。

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

問題:哪些 Proxy 路徑後置字串會導致系統在部分政策執行?就像「match」運算子一樣,在本例中只有一個可能。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?是,因為 Proxy 路徑後置字串與「/cat」完全相符。如果後置字串是 /bat/dog 或任何其他,就不會執行。

現在,我們要使用「*」量碼建立規則運算式。這個量詞會比對零或多個上述字元。

<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?不!「*」量器會比對零個或多個前方 字元,即「c」。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/ccccct

政策是否會執行?是,因為萬用字元符合零或多個上述字元。

接下來,我們使用「?」量碼,此值會比對上述字元一次,或完全不比對。

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?可以,「?」量詞會比對「前方」字元的零個或一次,也就是「a」。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/ct

政策是否會執行?可以,「?」量碼符合前述一個字元的一個「或無」。在這種情況下,沒有「a」字元,因此條件可評估為 True。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/caat

政策是否會執行?否。「?」量詞與前一個字元相符,也就是「a」。

接下來,我們會使用規則運算式的「[abc]」或「分組」樣式。會與 「a」、「b」或「c」字元相符。

<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?可以,這裡使用的是規則運算式,且「[cbr]」運算式與「c」、「b」或「r」相符。這些呼叫也符合:

GET http://artomatic-test.apigee.net/matchtest/bat

GET http://artomatic-test.apigee.net/matchtest/rat

不過,這並不代表相符的結果:

GET http://artomatic-test.apigee.net/matchtest/mat

問題:JavaRegex 運算子是否區分大小寫?

可以,假設您設定的條件如下:

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat

政策是否會執行?是,規則運算式會比對零個或上一個字元,也就是「a」。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cAt

問題:政策會執行嗎?

否,因為大寫「A」與小寫「a」不符。

MatchesPath

您也可以指定 MatchesPath 運算子,例如「~/」。這看起來與 Matches (~) 和 JavaRegex (~~) 運算子有點不同。但 matchPath 完全不同。

不過請記住,這個運算子會將路徑視為一系列部分。因此,如果路徑是 /animals/cats/wild,您可以將路徑視為包含「/animals」、「/cats」和「/wild」部分。

MatchesPath 運算子可讓您使用兩種萬用字元標記:單一星號 (*) 和雙星號 (**)。一個星號會與一個路徑元素相符。雙星號會比對一或多個路徑元素。

讓我們來看看下面這個例子。在此範例中,我們會測試變數 proxy.pathsuffix,這是 Edge 中的內建變數,用於儲存要求的路徑後置字串。請注意,您可以測試任何包含字串的流程變數值。

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

問題:哪些 Proxy 路徑後置字串會導致系統在部分政策執行?

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals

問題:政策會執行嗎?

否,因為條件需要「/*」所指定「/animals」後方的其他路徑元素。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/

政策是否會執行?是,路徑包含其他路徑元素 (「/animals/」後方的部分),但這只是空白的。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

政策是否會執行?是,因為路徑清楚含有「/animals」後方的元素 (「/cats」)

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

問題:政策會執行嗎?

否,因為單一星號只會與一個路徑元素相符,而這個 API 在「/animals」之後有多個元素。

現在,讓我們使用雙星號:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

問題:哪些 Proxy 路徑後置字串會導致系統在部分政策執行?

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals

政策是否會執行?否,因為條件需要至少一個「/**」指定的路徑元素。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/

政策是否會執行?

是,路徑包含其他路徑元素 (「/animals/」後方的部分),但這只是空白的。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

政策是否會執行?

是,因為該路徑至少有一個元素出現在「/animals」後方

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

政策是否會執行?

是,因為路徑在「/animals」之後有多個元素

混合星號

您可以使用單 (*) 和雙星號 (**) 星號的組合,進一步縮小路徑比對範圍。

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

API 呼叫:

以下所有 API 呼叫都會產生相符項目:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild/

GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian



GET http://artomatic-test.apigee.net/matchtest/animals/birds/wild/american/finches

API 資源

符合 REST 樣式的服務是一系列 API 資源。API 資源是一個 URI 路徑片段,可識別開發人員可透過呼叫 API 存取的部分實體。舉例來說,如果您的服務提供天氣預報和天氣預報,您的後端服務可能會定義兩個 API 資源:

  • http://mygreatweatherforecast.com/reports
  • http://mygreatweatherforecast.com/forecasts

建立 API Proxy (如「建立第一個 API Proxy」所示) 時,您至少要建立對應至後端服務的別名基本網址。例如:

後端基準網址 新的/對等 API Proxy 網址
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

此時,您可以使用任一基準網址對後端發出 API 呼叫。不過,使用 API Proxy 網址會開始很有趣。

除了使用 API Proxy 時,Edge 開始收集的 API 數據分析之外,Proxy 也能讓您定義對應至後端資源的條件式流程。基本上,「如果 GET 呼叫傳送至 /reports 資源,Edge 應執行其他作業」。

下圖顯示兩個最終存取相同後端的網址兩者的行為差異。其中一個是未經 Proxy 的資源網址,另一個是 Edge API Proxy,且具備指向相同後端資源的條件式流程。接下來,我們將詳細說明條件式流程。

API Proxy 如何對應至特定後端資源

只要 API Proxy 網址對應至後端服務的基準網址 (建立 Proxy 時),您就能將條件式流程新增至特定資源,例如前述的 /reports/forecasts 資源。

假設您想要讓 Edge 在呼叫 /reports/forecasts 資源時「執行特定操作」。此時,您不會指示 Edge 要監聽資源的呼叫,只是應監聽對這些資源的呼叫。只要使用條件即可。在 Edge API Proxy 中,您可以為 /reports/forecasts 建立條件式流程。基於概念性,下列 API Proxy XML 顯示這些條件的呈現方式。

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition>
    </Flow>
    <Flow name="forecasts">
        <Description/>
        <Request/>
        <Response/>
        <Condition>(proxy.pathsuffix MatchesPath "/forecasts") and (request.verb = "GET")</Condition>
    </Flow>
</Flows>

這些條件會顯示:「當 GET 要求從網址中包含 /reports/forecasts 時,Edge 會透過您附加至這些流程的政策執行您 (API 開發人員) 告知的任何動作,

以下是讓 Edge 在符合條件時怎麼做的例子。在下列 API Proxy XML 中,將 GET 要求傳送至 https://yourorg-test.apigee.net/mygreatweatherforecast/reports 時,Edge 會執行回應中的「XML-to-JSON-1」政策。

<Flows>
    <Flow name="reports">
        <Description/>
        <Request/>
        <Response>
            <Step>
                <Name>XML-to-JSON-1</Name>
            </Step>
        </Response>
        <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition>
</Flow>

除了這些選用的條件式流程以外,每個 API Proxy 也都有兩個預設流程:一個是在條件流程之前執行的 <PreFlow>,以及在條件式流程之後執行的 <PostFlow>。對 API Proxy 發出任何呼叫時,這些指令有助於執行政策。舉例來說,如果您想透過每次呼叫驗證應用程式的 API 金鑰 (無論存取的後端資源為何),都可以在 <PreFlow> 上放置「驗證 API 金鑰」政策。如要進一步瞭解流程,請參閱設定流程一文。

建立前往後端資源的條件式流程

您可以自行選擇是否要定義 API Proxy 中後端資源的條件式流程。不過,這些條件式流程可讓您套用精細的管理和監控功能。

包括:

  • 採用能反映 API 模型語意的管理機制
  • 將政策和指令碼行為套用至個別資源路徑 (URI)
  • 為 Analytics (分析) 服務收集精細的指標

舉例來說,假設您需要將不同類型的邏輯套用至後端 /developers 至 /apps 資源,

如要這麼做,請在 API Proxy 中新增 /developers/apps 兩個條件式流程。

在 API Proxy 編輯器導覽器窗格的「開發」檢視畫面中,按一下 Proxy 端點中預設旁邊的 + 圖示

在「New Conditional Flow」視窗中,輸入下列鍵設定:

  • 流程名稱:開發人員
  • 「條件類型」:路徑
  • 路徑:/developers

如果在 URI 結尾使用 /developers 將呼叫傳送至 Proxy,就會觸發條件並執行政策。

現在請為 /apps 新增條件式流程,並假設您想在要求中同時針對 URI 和 POST 動詞觸發條件。設定包括設定下列項目:

  • 流程名稱:應用程式
  • 條件類型:路徑和動詞
  • 路徑:/apps
  • 動詞:POST

如果呼叫在 URI 和 POST 動詞末端使用 /apps 傳送至 Proxy,則會觸發條件並執行政策。

在「Navigator」窗格中,您會看到「應用程式」和「開發人員」流程的新流程。

選取任一流程,即可在 API Proxy 編輯器程式碼檢視畫面中查看條件流程設定:

<Flow name="Apps">
    <Description>Developer apps registered in Developer Services</Description>
    <Request/>
    <Response/>
    <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition>
</Flow>

如您所見,API 資源只是條件式流程,用於評估傳入要求的 URI 路徑。(Proxy.pathsuffix 變數會根據在 ProxyEndpoint 設定中設定的 BasePath,來識別要求 URI)。

您定義的每個 API 資源,都是由 API Proxy 中的條件式流程實作。(請參閱設定流程)。

將 API Proxy 部署至測試環境後,請按照下列要求:

http://{org_name}-test.apigee.net/{proxy_path}/apps

會使條件評估為 True,並執行這個流程及所有相關聯的政策。

以下條件範例使用 Java 規則運算式來辨識對 /apps 資源發出的呼叫,無論呼叫是否包含正斜線 (/apps/apps/**):

<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>

如要進一步瞭解這類條件,請參閱 Apigee 社群中的「如何比對...」。

建立階層式 URI 模型

在某些情況下,您有階層的 API 資源。舉例來說,Developer Services API 可讓您列出屬於開發人員的所有應用程式。URI 路徑如下:

/developers/{developer_email}/apps

您可能有資源為集合中的每個實體產生專屬 ID,有時註解如下所示:

/genus/:id/species

這個路徑同樣適用於下列兩個 URI:

/genus/18904/species
/genus/17908/species

如要在 API 資源中表示這個結構,您可以使用萬用字元。例如:

/developers/*/apps
/developers/*example.com/apps
/genus/*/species

會以適當方式將這些階層 URI 解析為 API 資源。

在某些情況下,尤其是對於深度階層 API 而言,建議您直接解析特定 URI 片段下的所有內容。只要在資源定義中使用雙星號萬用字元即可。例如,如果您定義下列 API 資源:
/developers/**

該 API 資源會解析下列 URI 路徑:

/developers/{developer_email}/apps
/developers/{developer_email}/keys
/developers/{developer_email}/apps/{app_id}/keys

API Proxy 定義中的條件式流程條件看起來會像這樣:

<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>

其他示例

已附加至 RouteRule 的條件

<RouteRule name="default">
 <!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint-->
  <Condition>request.header.content-type = "text/xml"</Condition>
  <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint>
</RouteRule>

附加至政策的條件

<Step>
<!--the policy MaintenancePolicy only executes if the response status code is exactly 503-->
  <Condition>response.status.code = 503</Condition>
  <Name>MaintenancePolicy</Name>
</Step>

條件式流程

<!-- this entire flow is executed only if the request verb is a GET-->
<Flow name="GetRequests">
  <Condition>request.verb="GET"</Condition>
  <Request>
    <Step>
<!-- this policy only executes if request path includes a term like statues-->
<Condition>request.path ~ "/statuses/**"</Condition>
      <Name>StatusesRequestPolicy</Name>
    </Step>
  </Request>
  <Response>
    <Step>
<!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400-->
<Condition>(response.status.code = 503) or (response.status.code = 400)</Condition>
      <Name>MaintenancePolicy</Name>
    </Step>
  </Response>
</Flow>

條件中的範例運算子

以下列舉幾個可用於建立條件的運算子:

  • request.header.content-type = "text/xml"
  • request.header.content-length < 4096 && request.verb = "PUT"
  • response.status.code = 404 || response.status.code = 500
  • request.uri MatchesPath "/*/statuses/**"
  • request.queryparam.q0 NotEquals 10

實際範例:在路徑結尾忽略「/」

邊緣開發人員通常會想要處理「/cat」和「/cat/」這兩個路徑後置字串。這是因為部分使用者或用戶端可能會在路徑結尾加上額外斜線,藉此呼叫 API,您必須在條件陳述式中處理這一點。這種確切用途 已就在 Apigee 社群中討論

您也可以視需要使用規則運算式來達成這個目的:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

建議您選擇這個。清晰可讀。

對規則運算式執行同樣的操作也可以這樣括號可用來將陳述式的規則運算式部分分組,但並非必要。

<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat
or

GET http://artomatic-test.apigee.net/matchtest/cat/

政策是否會執行?可以,請注意,在規則運算式中,「?」字元代表:比對零個或一個上述字元。因此,「/cat」和「/cat/」都相符。

API 呼叫:

GET http://artomatic-test.apigee.net/matchtest/cat/spotted

政策是否會執行?不可以。規則運算式會比對前零個字元,或只比對一個字元,其他內容則一概不允許。

將任意字串與 JavaRegex 進行比對

在本主題的所有範例中,我們會說明如何比對其中一個內建流程變數:proxy.pathsuffix。好消息是,您可以針對任何任意字串或流程變數進行模式比對,無論它是否為 Proxy.pathsuffix 等內建流程變數。

舉例來說,如果您的條件會測試任意字串 (可能是後端酬載中傳回的字串,或是驗證伺服器查詢傳回的字串),您可以使用比對運算子進行測試。如果您使用 JavaRegex,系統會比較規則運算式與整個主旨字串。如果主旨為「abc」,且規則運算式為「[a-z]」,就代表沒有相符的項目,因為「[a-z]」與「單一」alpha 字元完全相符。運算式「[a-z]+」的功用與「[a-z]*」和「[a-z]{3}」一樣。

以下是具體範例。假設驗證伺服器以半形逗號分隔字串「editor, author, 訪客」傳回角色清單。

「editor」只是整個字串的一部分,因此這項建構將無法運作,以便測試編輯者角色是否存在。

<Condition>returned_roles ~~ "editor"</Condition>

不過,這個結構可以運作:

<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>

之所以能正常運作,原因是

在這個範例中,您也可以使用「match」運算子來測試「editor」:

<Condition>returned_roles ~~ "*editor*")</Condition>

不過,如果您需要更高的精確度,JavaRegex 通常是更好的選擇。

JavaRegex 運算式中的逸出雙引號

使用 Condition 語法時,必須用雙引號括住 JavaRegex 運算式。因此,如果您的規則運算式運算式包含雙引號,則需要透過其他方式比對。答案是萬國碼舉例來說,假設您傳入的標頭包含雙引號,如下所示:
 -H 'content-type:multipart/related; type="application/xop+xml"'
如果您嘗試在 Regex 條件中比對該標頭,就會發生「Invalid Condition」錯誤,因為運算式包含雙引號:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
解決方法是將以 ASCII 為基礎的雙引號替換為對等的萬國碼 (Unicode) \u0022。舉例來說,以下運算式有效,並會產生預期結果:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"