含有流程變數的條件

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

條件式陳述式是所有程式設計語言中常見的控制結構。如同程式語言,API Proxy 設定支援流程、政策、步驟和 RouteRule 的條件式陳述式。定義條件陳述式,即可為 API 定義動態行為。這項動態行為可讓您執行各種操作,例如只針對行動裝置將 XML 轉換為 JSON,或是根據要求訊息的內容類型或 HTTP 動詞,將要求導向後端網址。

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

設定條件式陳述式

您可以使用條件變數的組合,在 API Proxy 中實作條件式行為。條件式陳述式是使用 Condition 元素建立。以下是空條件:

<Condition></Condition>

如要建立條件陳述式,請使用下列語法新增條件運算子和變數:

<Condition>VARIABLE_NAME OPERATOR "VALUE"</Condition>

例如:

<Condition>request.verb = "GET"</Condition>

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

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

如要定義 API Proxy 對後端 API 資源的條件式流程,請參閱「建立對後端 API 資源的條件式流程」一文。如需完整的條件清單,請參閱「條件參考資料」。

變數

條件會透過評估變數的值來執行工作。變數是 API Proxy 執行的 HTTP 交易屬性,或是 API Proxy 設定本身的屬性。每當 API Proxy 從應用程式取得要求時,Apigee 就會填入一長串變數清單,這些變數與系統時間、應用程式的網路資訊、訊息的 HTTP 標頭、API Proxy 設定、政策執行等相關。這會建立豐富的內容,可用於設定條件式陳述式。

變數一律使用點號標記法。舉例來說,要求訊息中的 HTTP 標頭可做為名為 request.header.HEADER_NAME 的變數使用。因此,如要評估 Content-type header,您可以使用變數 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>

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

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

將條件附加至流程時,您會建立條件式流程。只有在條件評估為 true 時,系統才會執行條件式流程。您可以為條件式流程附加任意數量的政策。條件式流程可讓您為符合特定條件的請求或回應訊息,設計高度專門的處理規則。

舉例來說,如要建立只有在要求動詞為 GET 時才執行的流程:

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

如要為 GET 要求建立一個流程,並為 POST 要求建立另一個流程,請按照下列步驟操作:

<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>

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

在上述 ProxyEndpoint 設定中,Apigee 會檢查 request.header.User-Agent 變數的值,判斷條件是否會評估為 true。

如果條件確實評估為 true,也就是變數 request.header.User-Agent 的值等於 Mozilla,則會執行條件式流程,並強制執行名為 ConvertToJSONXMLtoJSON 政策。如果沒有,系統就不會執行流程,並將未經修改的 XML 回應 (以 XML 格式) 傳回給要求應用程式。

範例 2

以下是需要將回應訊息從 XML 轉換為 JSON 的具體範例,但僅限於行動裝置。首先,建立政策,將 Weather API 的 XML 格式回應轉換為 JSON:

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

上述政策設定會告知 API 代理程式接收回應訊息,並使用預設設定執行 XML 至 JSON 的轉換,然後將結果寫入新的回應訊息。(如果您要將 要求訊息從 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。如要啟用這類動態行為,您必須在流程中新增條件陳述式。

測試條件式流程

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

curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282

或在 Python 可用的情況下,以美觀的格式列印:

curl -H "User-Agent:Mozilla" http://example.com/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://example.com/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 流程中使用模式比對和條件。

運算子

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

相符

我們先來看看 Matches~ 條件運算子。這兩個運算子相同,英文版的 Matches 被視為更易讀的選項。

摘要:Matches 運算子有兩種可能的結果。您可以使用字串常值比對,或使用 * 進行萬用字元比對。如您所料,萬用字元會比對零個或多個字元。接下來是運作方式範例

以下 XML 顯示步驟條件。當條件評估為 true 時,它會執行 SomePolicy 政策。在本例中,我們測試變數 proxy.pathsuffix,這是 Apigee 內建的變數,用於儲存要求的路徑後置字串。不過,您可以測試任何包含字串的流程變數值。因此,在這種情況下,如果傳入要求的基本路徑為 /animals,而要求為 /animals/cat,則路徑後置字串為文字字串 /cat

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

問題:哪個 Proxy 路徑後置字會導致 SomePolicy 執行?只有一種可能性。

API 呼叫:

GET http://example.com/matchtest/cat

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

請考慮下列使用萬用字元 * 的條件陳述式:

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?是的,因為萬用字元會比對任何字元,而「"/cat」是符合的字元。

API 呼叫:

GET http://example.com/matchtest/bat

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

API 呼叫:

GET http://example.com/matchtest/owl

政策是否執行?當然不是,雖然萬用字元會比對 o,但字母 wl 並未比對。

接著,讓我們將萬用字元移至後置字串結尾:

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?是的,因為萬用字元可比對零個或多個任意字元。

API 呼叫:

GET http://example.com/matchtest/bat

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

API 呼叫:

GET http://example.com/matchtest/cat123

政策是否執行?是的,萬用字元會比對零個或多個任意字元,因此 123 會產生相符的結果。

API 呼叫:

GET http://example.com/matchtest/cat/bird/mouse

政策是否執行?是的,因為萬用字元會比對零個或多個任意字元,因此 /bird/mouse 會產生相符結果。請注意,這類運算式會導致問題,因為它會比對常值字元後面的所有內容!

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

可以。假設您有以下條件:

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?否,萬用字元會比對任何字母 (不區分大小寫),但小寫 aA 不相符。

API 呼叫:

GET http://example.com/matchtest/bAt

政策是否執行?是,兩者相符。

問題:如何使用 Matches 運算子轉義字元?

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

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?否,Matches 運算子會尋找文字常值字串 c*at

API 呼叫:

GET http://example.com/matchtest/c*at

問題:政策是否執行?

是的,這個路徑雖然有點不尋常,但確實符合。

JavaRegex

如您所見,Matches 運算子非常適合用於簡單的情況。不過,您可以使用其他運算子,例如 JavaRegex 或 ~~ 運算子。這兩個運算子相同,但 JavaRegex 的易讀性較高。之所以稱為 JavaRegex,是因為它允許規則運算式模式比對,且 Apigee 遵循 Java 語言中 java.util.regex 套件中的類別所遵循的規則。JavaRegex 運算子的運作方式與 Matches 運算子截然不同,因此請務必不要混淆這兩者!

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

以下程式碼為步驟條件。如果條件評估為 true,就會執行 SomePolicy 政策。在本例中,我們測試變數 proxy.pathsuffix,這是 Apigee 內建的變數,用於儲存要求的路徑後置字串。如果傳入要求的基本路徑為 /animals,而要求為 /animals/cat,則路徑後置字串為文字字串 /cat

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

問題:哪個 Proxy 路徑後置字會導致 SomePolicy 執行?就像使用 Matches 運算子一樣,在這種情況下只有一種可能性。

API 呼叫:

GET http://example.com/matchtest/cat

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

接下來,我們將使用 * 量詞建立規則運算式。這個量詞會比對前面零個或多個字元。

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?不行!* 量詞會比對零個或多個前面 字元,也就是 c

API 呼叫:

GET http://example.com/matchtest/ccccct

政策是否執行?是的,因為萬用字元會比對前一個字元零個或多個。

接著,我們使用 ? 量詞,該量詞會比對前一個字元一次,或完全不比對。

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?可以。? 量詞會比對「前一個」字元 (即 a) 出現 0 或 1 次。

API 呼叫:

GET http://example.com/matchtest/ct

政策是否執行?可以。? 量詞會比對前一個字元的一個或無。在本例中,沒有 a 字元,因此條件會評估為 true

API 呼叫:

GET http://example.com/matchtest/caat

政策是否執行?否。? 量詞會比對前一個字元 (a) 的一個

接著,我們使用 [abc]分組樣式的規則運算式。會比對 abc 字元。

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?可以。我們在這裡使用規則運算式,[cbr] 運算式會比對 cbr。以下呼叫也符合條件:

GET http://example.com/matchtest/bat

GET http://example.com/matchtest/rat

但這並非相符項目:

GET http://example.com/matchtest/mat

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

可以。假設您有以下條件:

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

API 呼叫:

GET http://example.com/matchtest/cat

政策是否執行?是的,規則運算式會比對前一個字元 (a) 的零個或一個。

API 呼叫:

GET http://example.com/matchtest/cAt

問題:政策是否執行?

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

MatchesPath

您也可以像這樣指定 MatchesPath 運算子 ~/。它有點像 Matches (~) 和 JavaRegex (~~) 運算子。但 MatchesPath 完全不同。

請記住,這個運算子會將路徑視為一系列的部分。因此,如果路徑為 /animals/cats/wild,您可以將路徑視為由 /animals/cats/wild 等部分組成。

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

我們來看個例子。在這個範例中,我們測試變數 proxy.pathsuffix,這是 Apigee 內建的變數,用於儲存要求的路徑後置字串。不過,您可以測試任何包含字串的流程變數值。

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

問題:哪個 Proxy 路徑後置字會導致 SomePolicy 執行?

API 呼叫:

GET http://example.com/matchtest/animals

問題:政策是否執行?

否,因為條件需要在 /animals 後方加入另一個路徑元素,如 /* 所指定。

API 呼叫:

GET http://example.com/matchtest/animals/

政策是否執行?是的,路徑確實有另一個路徑元素 (/animals/ 後方的部分),但只是空白而已。

API 呼叫:

GET http://example.com/matchtest/animals/cats

政策是否執行?是的,因為路徑中明確有 /animals 後面的元素 (/cats)

API 呼叫:

GET http://example.com/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 路徑後置字會導致 SomePolicy 執行?

API 呼叫:

GET http://example.com/matchtest/animals

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

API 呼叫:

GET http://example.com/matchtest/animals/

政策是否已執行?

是的,路徑確實有另一個路徑元素 (/animals/ 後方的部分),但只是空白而已。

API 呼叫:

GET http://example.com/matchtest/animals/cats

政策是否已執行?

是的,因為路徑至少包含一個 /animals 後面的元素

API 呼叫:

GET http://example.com/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://example.com/matchtest/animals/cats/wild/

GET http://example.com/matchtest/animals/dogs/wild/austrailian

and

GET http://example.com/matchtest/animals/birds/wild/american/finches

API 資源

RESTful 服務是 API 資源的集合。API 資源是 URI 路徑片段,可用於識別開發人員可透過呼叫 API 存取的實體。舉例來說,如果您的服務提供天氣報告和天氣預報,後端服務可能會定義兩個 API 資源:

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

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

後端基準網址 新的/等效的 API Proxy 網址
http://mygreatweatherforecast.com http://example.com/mygreatweatherforecast

此時,您可以使用任一基本網址對後端發出 API 呼叫。不過,使用 API Proxy 網址後,情況就會變得有趣。

除了 Apigee 在您使用 API Proxy 時開始收集的 API 分析資料之外,Proxy 還可讓您定義與後端資源對應的條件式流程。從本質上來說,如果 GET 呼叫進入 /reports 資源,Apigee 應採取某些行動。

下圖顯示最終存取相同後端的兩個網址之間的行為差異。一個是未經 Proxy 的資源網址,另一個則是 Apigee API Proxy,其中包含前往相同後端資源的條件流程。我們會在下文中詳細說明條件式流程。

如果是含有條件式流程的 Apigee API 代理程式網址,回應會將 XML 轉換為 JSON,並收集分析資料。

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

將 API Proxy 網址對應至後端服務的基礎網址 (在建立 Proxy 時),即可將條件式流程新增至特定資源,例如前述的 /reports/forecasts 資源。

假設您希望在 /reports/forecasts 資源收到呼叫時,讓 Apigee 執行某項動作。此時,您並未告知 Apigee 要做什麼,只是要它監聽對這些資源的呼叫。您可以使用條件來執行這項操作。在 Apigee 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 時,Apigee 會透過您 (API 開發人員) 附加至這些流程的政策,執行您指定的任何操作。」

以下範例說明如何告訴 Apigee 在符合條件時應採取哪些行動。在下列 API 代理程式 XML 中,當 GET 要求傳送至 https://example.com/mygreatweatherforecast/reports 時,Apigee 會在回應中執行 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

全新 Proxy 編輯器

如要新增條件式流程,請按照下列步驟操作:

  1. 在 Proxy 編輯器中選取「Develop」分頁。
  2. 在左側窗格中,依序選取「Proxy endpoints」>「default」

    在左側窗格中,依序選取「Proxy endpoints」>「default」。

  3. 按一下「回應」窗格上方的「+」按鈕。

    新增條件式流程按鈕

  4. 在「新增條件式流程」對話方塊中,輸入下列設定:
    • 流程名稱Developers
    • 條件類型Path
    • 路徑/developers

    新增條件式流程對話方塊。

    如果通話傳送至代理程式,且 URI 結尾有 /developers,系統就會觸發條件 (並執行政策)。

  5. 現在,請為 /apps 新增條件式流程,並假設您希望在要求中的 URI 和 POST 動詞上觸發條件。設定包括下列項目:
    • 流程名稱Apps
    • 條件類型Path and Verb
    • 路徑/apps
    • 動詞POST

    如果呼叫傳送至 Proxy,且 URI 結尾有 /appsPOST 動詞,系統就會觸發條件 (並執行政策)。

新增的流程會顯示在「Response」窗格中:

新增條件式流程對話方塊。

傳統 Proxy 編輯器

在 API Proxy 編輯器的「Navigator」窗格「Develop」窗格中,按一下「Proxy Endpoints」中的「default」旁邊的

當您將游標懸停在預設旁的加號上時,游標文字會顯示「新增流程」。

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

  • 流程名稱Developers
  • 條件類型Path
  • 路徑/developers

在「New Conditional Flow」窗格中,設定名為「Developers」的流程,並附上「App developers registered with Developer Services」的說明。

如果通話傳送至代理程式,且 URI 結尾有 /developers,系統就會觸發條件 (並執行政策)。

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

  • 流程名稱Apps
  • 條件類型Path and Verb
  • 路徑/apps
  • 動詞POST

在「New Conditional Flow」窗格中,設定名為「Apps」的流程,並將說明設為「Developer Services 中註冊的開發人員應用程式」。

如果呼叫傳送至 Proxy,且 URI 結尾有 /appsPOST 動詞,系統就會觸發條件 (並執行政策)。

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

應用程式和開發人員的新流程會顯示在「Proxy Endpoints」下方的「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://example.com/PROXY_PATH/apps

會導致條件評估為 true,並執行這個流程以及任何相關政策。

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

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

如要進一步瞭解這類條件,請參閱 如何不論是否有結尾的「/」來比對,詳見 Apigee 社群

模擬階層式 URI

在某些情況下,您會有階層式 API 資源。舉例來說,開發人員應用程式清單 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 代理定義中的條件流程限制條件:

<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

實際範例:忽略路徑結尾的 /

Apigee 開發人員通常會處理這兩個路徑後置字串:/cat/cat/。這是因為部分使用者或用戶端可能會在路徑結尾加上多餘的斜線來呼叫您的 API,您必須能夠在條件陳述式中處理這種情況。這個用途已在「如何比對網址,不論結尾是否有 '/'」一文中討論過。

如有需要,您可以不使用規則運算式達成這項目標,例如:

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

這是不錯的做法。內容清晰可辨。

不過,您也可以使用 Regex 執行相同的操作,如下所示。括號用於分組陳述式的規則運算式部分,但並非必要。

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

API 呼叫:

GET http://example.com/matchtest/cat
GET http://example.com/matchtest/cat/

政策是否執行?可以。請注意,在規則運算式中,? 字元代表:與前面字元比對零或一。因此,/cat/cat/ 都符合條件。

API 呼叫:

GET http://example.com/matchtest/cat/spotted

政策是否執行?否。規則運算式會比對零個或其中一個先前字元的出現次數,且不允許其他字元。

使用 JavaRegex 比對任意字串

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

舉例來說,如果您有一個條件要測試任意字串,可能是後端酬載中傳回的字串,或是從驗證伺服器查詢傳回的字串,您可以使用比對運算子來測試。如果您使用 JavaRegex,規則運算式會與整個主體字串進行比對。如果主旨是 abc,而規則運算式是 [a-z],則系統不會比對成功,因為 [a-z] 只會與「一個」英文字母字元相符。運算式 [a-z]+ 可正常運作,[a-z]*[a-z]{3} 也是如此。

我們來看看具體範例。假設驗證伺服器以逗號分隔的字串形式傳回角色清單:editor, author, guest

如要測試編輯者角色是否存在,這項結構就無法運作,因為 editor 只是整個字串的一部分。

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

不過,以下結構會運作:

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

這是因為它會考量單字斷開處和字串的任何其他部分,並使用 .* 前置字串和後置字串。

在這個範例中,您也可以使用 Matches 運算子測試 editor

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

不過,如果需要更精確的結果,JavaRegex 通常是較佳的選擇。

在 JavaRegex 運算式中逃逸雙引號

條件語法要求 JavaRegex 運算式以雙引號包圍,因此如果您有包含雙引號的規則運算式,就需要以其他方式進行比對。答案是 Unicode。舉例來說,假設您傳入的標頭包含雙引號,如下所示:

 -H 'content-type:multipart/related; type="application/xop+xml"'

如果您嘗試在正規表示式條件中比對該標頭,由於運算式包含雙引號,因此會收到 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)"