本頁內容適用於 Apigee 和 Apigee 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>
支援的條件運算子包括 =
(等於)、!=
(不等於) 和 >
(大於)。為方便閱讀,您也可以將條件式寫成:
text: equals
、notequals
、greaterthan
。
處理 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。
如要啟用動態行為,您可以將條件附加至流程、步驟和 RouteRule。
將條件附加至流程時,您會建立條件式流程。只有在條件評估為 true 時,才會執行條件式流程。您可以視需要將多項政策附加至條件式流程。條件式流程可讓您為符合特定條件的請求或回應訊息,制定高度專業的處理規則。
舉例來說,如要建立僅在要求動詞為 GET
時執行的 Flow,請按照下列步驟操作:
<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
以下範例顯示在 ProxyEndpoint 回應流程中設定的單一條件流程,名為 Convert-for-devices
。將條件新增為實體的元素,條件適用於該實體。在本範例中,條件是流程的元件。
因此,只要陳述式評估結果為 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
,則條件式流程會執行,並強制執行名為 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://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
運算子:簡單模式比對- JavaRegex 運算子:更精細地控管比對作業
MatchesPath
運算子:比對路徑片段
相符
我們先來看看 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
政策是否會執行?否,萬用字元會比對任何字母 (不區分大小寫),但小寫 a
不會比對 A
。
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
或其他字元,系統就不會執行。
現在,我們來使用 *
量詞建立規則運算式。這個量詞會比對前接字元 0 次以上。
<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
) 出現零次或一次。
API 呼叫:
GET http://example.com/matchtest/ct
政策是否會執行?可以。?
量詞會比對前接字元或零個。在本例中,沒有 a
字元,因此條件評估結果為 true
。
API 呼叫:
GET http://example.com/matchtest/caat
政策是否會執行?否。?
量詞會比對前接字元其中一個,也就是 a
。
接著,我們會使用 [abc]
或分組樣式的規則運算式。與字元 a
、b
或 c
相符。
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
API 呼叫:
GET http://example.com/matchtest/cat
政策是否會執行?可以。我們在這裡使用規則運算式,而 [cbr]
運算式會比對 c
、b
或 r
。以下呼叫也是相符項目:
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
政策是否會執行?是,規則運算式會比對前接字元 0 或 1 次,也就是 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
和
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 網址時,情況就開始變得有趣。
除了使用 API Proxy 時,Apigee 開始收集的 API 數據分析資料外,Proxy 也可讓您定義對應至後端資源的條件式流程。基本上,如果 GET
呼叫進入 /reports
資源,Apigee 應採取行動。
下圖顯示兩個最終存取相同後端的網址,在行為上的差異。一個是未經過 Proxy 的資源網址,另一個則是 Apigee API Proxy,其中包含前往相同後端資源的條件流程。我們將在下文詳細說明條件流程。
API Proxy 如何對應至特定後端資源
API Proxy 網址會對應至後端服務的基本網址 (建立 Proxy 時),您可以將條件流程新增至特定資源,例如先前提及的 /reports
和 /forecasts
資源。
假設您希望 Apigee 在呼叫 /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 代理發出 任何呼叫時,這些項目可用於執行政策。舉例來說,如果您想在每次呼叫時驗證應用程式的 API 金鑰,無論存取的後端資源為何,都可以在 <PreFlow>
上放置「驗證 API 金鑰」政策。如要進一步瞭解流程,請參閱「設定流程」。
建立後端資源的條件流程
在 API Proxy 中定義後端資源的條件流程完全是選用功能。 不過,這些條件式流程可讓您進行精細的管理和監控。
包括:
- 以反映 API 模型語意的方式套用管理功能
- 對個別資源路徑 (URI) 套用政策和指令碼行為
- 收集 Analytics 服務的精細指標
舉例來說,假設您需要將不同類型的邏輯套用至後端 /developers
至 /apps
資源。
如要這麼做,請在 API Proxy 中新增兩個條件流程:/developers
和 /apps
。
Apigee Cloud 控制台
如要新增條件流程,請按照下列步驟操作:
- 在 Proxy 編輯器中選取「開發」分頁標籤。
- 在左側窗格中,依序選取「Proxy endpoints」>「default」。
- 按一下「回覆」窗格上方的「+」按鈕。
- 在「新增條件式流程」對話方塊中,輸入下列設定:
- 流程名稱:
Developers
- 條件類型:
Path
- 路徑:
/developers
如果將呼叫傳送至 Proxy,且 URI 結尾為
/developers
,系統就會觸發條件 (並執行政策)。 - 流程名稱:
- 現在請為
/apps
新增條件流程,並假設您希望在要求中的 URI 和POST
動詞觸發條件。設定時需要指定下列項目:- 流程名稱:
Apps
- 條件類型:
Path and Verb
- 路徑:
/apps
- 動詞:
POST
如果呼叫傳送至 Proxy,且 URI 結尾為
/apps
,並使用POST
動詞,就會觸發條件 (並執行政策)。 - 流程名稱:
新增的流程會顯示在「回應」窗格中:
傳統版 Apigee UI
在 API Proxy 編輯器的「Develop」(開發)窗格中,按一下「Navigator」(導覽器)窗格的「Proxy Endpoints」(Proxy 端點) 旁邊的 「default」(預設)。
在「New Conditional Flow」(新增條件流程) 視窗中,輸入下列主要設定:
- 流程名稱:
Developers
- 條件類型:
Path
- 路徑:
/developers
如果將呼叫傳送至 Proxy,且 URI 結尾為 /developers
,系統就會觸發條件 (並執行政策)。
現在請為 /apps
新增條件流程,並假設您希望在要求中的 URI 和 POST
動詞觸發條件。設定時需要指定下列項目:
- 流程名稱:
Apps
- 條件類型:
Path and Verb
- 路徑:
/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
變數會識別要求 URI,該要求 URI 遵循 ProxyEndpoint 設定中設定的 BasePath)。
您定義的每個 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 社群中的「How to match regardless whether there is a trailing "/" ...」。
建立階層式 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 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
實務範例:忽略路徑結尾的 �/
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 執行相同操作,如下所示。括號用於將陳述式的 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 運算式必須以雙引號括住,因此如果您的 regex 運算式包含雙引號,就必須使用其他方式來比對。答案是 Unicode。舉例來說,假設您傳遞的標頭包含雙引號,如下所示:
-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)"