含有流程變數的條件

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

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

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

設定條件式陳述式

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

<Condition></Condition>

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

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

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

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

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

變數

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

變數一律使用點號標記法。舉例來說,要求訊息中的 HTTP 標頭可做為名為 request.header.{header_name} 的變數使用。因此,如要評估內容類型標頭,您可以使用變數 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 建立不同的流程,請按照下列步驟操作:

<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 政策。如果沒有,系統就不會執行流程,並將未經修改的 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://{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 流程中使用模式比對和條件。

運算子

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

相符組合

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

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

以下 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 路徑後置字會導致 SomePolicy 執行?目前只有一個可能。

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

政策是否執行?是,案件相符。

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

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

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

API 呼叫:

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

政策是否執行?否,相符運算子會尋找「c*at」這個文字字串。

API 呼叫:

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

問題:政策是否執行?

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

JavaRegex

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

摘要:「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 路徑後置字串會導致 SomePolicy 執行?就像使用「Matches」運算子一樣,在這種情況下只有一種可能性。

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 (~~) 運算子。但 MatchesPath 則完全不同。

請記住,這個運算子會將路徑視為一系列的部分。因此,如果路徑為 /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 路徑後置字會導致 SomePolicy 執行?

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 路徑後置字會導致 SomePolicy 執行?

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

and

GET http://artomatic-test.apigee.net/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://{your_org}-{environment}.apigee.net/mygreatweatherforecast

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

除了 Edge 在您使用 API Proxy 時開始收集的 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 代理程式 XML 中,當 GET 要求傳送至 https://yourorg-test.apigee.net/mygreatweatherforecast/reports 時,Edge 會在回應中執行「XML 至 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 編輯器導覽窗格中的「Develop」檢視畫面中,按一下「Proxy Endpoints」中「default」旁邊的「+」圖示

在「New Conditional Flow」(新增條件式流程) 視窗中,輸入下列關鍵設定:

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

如果在 URI 結尾使用 /developers 呼叫 Proxy,就會觸發條件 (並觸發政策)。

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

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

如果傳送至 Proxy 的呼叫在 URI 結尾處包含 /apps 和 POST 動詞,系統就會觸發條件 (並執行政策)。

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

選取其中一個流程,即可在 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 資源。舉例來說,開發人員服務 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

實務範例:忽略路徑結尾的「/」

Edge 開發人員通常會想處理這兩個路徑後置字串:「/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>

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

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

<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]」只會與「一個」英文字母相符。運算式「[a-z]+」可正常運作,而「[a-z]*」和「[a-z]{3}」也一樣。

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

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

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

不過,以下結構會運作:

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

這種做法會考量字詞符號和字串中的其他任何部分加上 .* 前置字元和後置字串,所以能夠順利運作。

在本例中,您也可以使用比對運算子來測試「editor」:

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

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

在 JavaRegex 運算式中逃逸雙引號

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