使用政策組合

您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件
info

本主題將說明如何使用政策組合建立混搭內容。 政策組合是 Apigee Proxy 模式,可讓您使用政策,將多個後端目標的結果合併為單一回應。

如要瞭解政策組合的一般總覽,請參閱「API Proxy Cookbook patterns」(API Proxy 食譜模式) 中的「The policy composition pattern」(政策組合模式)。

下載並試用程式碼範例

關於本教戰手冊範例

這個食譜範例說明名為「政策組合」的 API Proxy 模式。這個模式提供一種方式 (還有其他方式),可將多個後端來源的資料混搭在一起。更廣義來說,這個主題說明如何結合及串連政策,以產生所需結果。如要大致瞭解這個模式和其他相關模式,請參閱 API Proxy Cookbook 模式

這裡討論的範例會使用政策組合,從下列兩個不同的公開 API 混搭資料:

  • Google Geocoding API:這項 API 會將地址 (例如「1600 Amphitheatre Parkway, Mountain View, CA」) 轉換為地理座標 (例如緯度 37.423021 和經度 -122.083739)。
  • Google 海拔高度 API:這個 API 提供簡易介面,可用來查詢地表位置的海拔高度資料。在本範例中,Geocoding API 傳回的座標會做為這個 API 的輸入內容。

應用程式開發人員會使用兩個查詢參數 (郵遞區號和國家/地區 ID) 呼叫這個 API Proxy:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

回應是 JSON 物件,包含所提供郵遞區號區域中心的地理編碼位置 (經緯度),以及該地理編碼位置的海拔高度。

{  
   "ElevationResponse":{  
      "status":"OK",
      "result":{  
         "location":{  
            "lat":"39.7500713",
            "lng":"-74.1357407"
         },
         "elevation":"0.5045232",
         "resolution":"76.3516159"
      }
   }
}

事前準備

如要簡要瞭解政策組合模式,請參閱 API Proxy Cookbook 模式中的「政策組合模式」。

在探索這個食譜範例之前,您也應該熟悉下列基本概念:

  • 瞭解政策,以及如何將政策附加至 Proxy。如要瞭解政策的相關基本概念,請參閱「什麼是政策?」。
  • API Proxy 流程的結構,如「設定流程」一文所述。您可以透過流程指定 API Proxy 執行政策的順序。在本例中,系統會建立多項政策,並新增至 API Proxy 的流程。
  • API Proxy 專案在檔案系統中的組織方式,如「API Proxy 設定參考資料」一文所述。本主題示範本機開發作業 (以檔案系統為基礎),而非雲端開發作業 (您可以使用管理 UI 開發 API Proxy)。
  • 使用 API 金鑰驗證。這是最簡單的應用程式式安全機制,可為 API 設定。詳情請參閱「API 金鑰」。您也可以參閱透過要求 API 金鑰保護 API 安全教學課程。
  • 具備 XML 實務知識。在本範例中,我們會使用檔案系統中的 XML 檔案,建構 API Proxy 及其政策。

如果您已下載程式碼範例,可以在 mashup-policy-cookbook 範例資料夾中找到本主題討論的所有檔案。以下各節將詳細討論程式碼範例。

隨波逐流

在說明政策之前,我們先來看看範例 API Proxy 的主要流程。如下所示的流程 XML 包含這個 Proxy 的許多資訊,包括使用的政策,以及呼叫這些政策的位置。

在下載的範例中,您可以在 doc-samples/policy-mashup-cookbook/apiproxy/proxies/default.xml 檔案中找到這個 XML。

<ProxyEndpoint name="default">
  <Flows>
    <Flow name="default">
      <Request>
            <!-- Generate request message for the Google Geocoding API -->
            <Step><Name>GenerateGeocodingRequest</Name></Step>
            <!-- Call the Google Geocoding API -->
            <Step><Name>ExecuteGeocodingRequest</Name></Step>
            <!-- Parse the response and set variables -->
            <Step><Name>ParseGeocodingResponse</Name></Step>
            <!-- Generate request message for the Google Elevation API -->
            <Step><Name>AssignElevationParameters</Name></Step>
      </Request>
      <Response>
            <!-- Parse the response message from the Elevation API -->
            <Step><Name>ParseElevationResponse</Name></Step>
            <!-- Generate the final JSON-formatted response with JavaScript -->
            <Step><Name>GenerateResponse</Name></Step>
      </Response>
    </Flow>
  </Flows>

  <HTTPProxyConnection>
    <!-- Add a base path to the ProxyEndpoint for URI pattern matching-->
    <BasePath>/policy-mashup-cookbook</BasePath>
    <!-- Listen on both HTTP and HTTPS endpoints -->
    <VirtualHost>default</VirtualHost>
    <VirtualHost>secure</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="default">
    <!-- Connect ProxyEndpoint to named TargetEndpoint under /targets -->
    <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

以下是流程元素的摘要。

  • <Request> - <Request> 元素由多個 <Step> 元素組成。每個步驟都會呼叫我們將在本主題其餘部分建立的其中一項政策。這些政策與建立要求訊息、傳送要求訊息,以及剖析回應有關。本主題結束時,您將瞭解這些政策各自扮演的角色。
  • <Response> - <Response> 元素也包含 <Steps>。這些步驟也會呼叫負責處理目標端點 (Google Elevation API) 最終回應的政策。
  • <HttpProxyConnection> - 這個元素會指定應用程式連線至這個 API Proxy 的詳細資料,包括 <BasePath>,這個元素會指定如何呼叫這個 API。
  • <RouteRule> - 這個元素會指定處理完傳入要求訊息後,系統應立即執行的動作。在本例中,TargetEndpoint 名為。 我們會在稍後的主題中,進一步說明這個重要步驟。

建立政策

以下各節將討論組成這個政策組合範例的各項政策。

建立第一個 AssignMessage 政策

第一個 AssignMessage 政策 (如下所示) 會建立要求訊息,並傳送至 Google Geocoding 服務。

我們先從政策程式碼開始,然後再詳細說明各個元素。在範例下載內容中,您可以在 doc-samples/policy-mashup-cookbook/apiproxy/policies/GenerateGeocodingRequest.xml 檔案中找到這個 XML。

<AssignMessage name="GenerateGeocodingRequest">
  <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo>
  <Set>
    <QueryParams>
      <QueryParam name="address">{request.queryparam.postalcode}</QueryParam>
      <QueryParam name="region">{request.queryparam.country}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
    <Verb>GET</Verb>
  </Set>
  <!-- Set variables for use in the final response -->
  <AssignVariable>
    <Name>PostalCode</Name>
    <Ref>request.queryparam.postalcode</Ref>
  </AssignVariable>
  <AssignVariable>
    <Name>Country</Name>
    <Ref>request.queryparam.country</Ref>
  </AssignVariable>
</AssignMessage>

以下簡要說明這項政策的要素。如要進一步瞭解這項政策,請參閱「指派訊息政策」。

  • <AssignMessage name> - 為這項政策命名。在流程中參照政策時,會使用這個名稱。
  • <AssignTo> - 建立名為 GeocodingRequest 的變數。 這個變數會封裝要求物件,並由 ServiceCallout 政策傳送至後端。
  • <QueryParams> - 設定後端 API 呼叫所需的查詢參數。在這種情況下,Geocoding API 需要知道地點 (以郵遞區號和國家/地區 ID 表示)。這項資訊是由應用程式使用者提供,我們只是在此擷取。API 需要 sensor 參數,且該參數為 true 或 false,我們在此將其硬式編碼為 false。
  • <動詞> - 在這個案例中,我們向 API 提出簡單的 GET 要求。
  • <AssignVariable> - 這些變數會儲存傳遞至 API 的值。在本例中,變數稍後會在傳回給用戶端的 回應中存取。

使用 ServiceCallout 傳送要求

政策組合序列的下一個步驟是建立 ServiceCallout 政策。下列 ServiceCallout 政策會將我們在先前的 AssignMessage 政策中建立的要求物件,傳送至 Google Geocoding 服務,並將結果儲存至名為 GeocodingResponse 的變數。

和先前一樣,我們先來看看程式碼。詳細說明如下。如要進一步瞭解這項政策,請參閱服務說明政策。在下載的範例中,您可以在 doc-samples/policy-mashup-cookbook/apiproxy/policies/ExecuteGeocodingRequest.xml 檔案中找到這個 XML。

<ServiceCallout name="ExecuteGeocodingRequest">
  <Request variable="GeocodingRequest"/>
  <Response>GeocodingResponse</Response>
  <HTTPTargetConnection>
    <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
  </HTTPTargetConnection>
</ServiceCallout>

以下簡要說明這項政策的要素。

  • <ServiceCallout> - 與先前的政策相同,這項政策也有名稱。
  • <要求變數>:這是您在 AssignMessage 政策中建立的變數。封裝傳送至後端 API 的要求。
  • <Response> - 這個元素會命名變數,回應會儲存在該變數中。如您所見,ExtractVariables 政策稍後會存取這個變數。
  • <HTTPTargetConnection> - 指定後端 API 的目標網址。在本例中,我們指定 API 傳回 JSON 回應。

現在我們有兩項政策,一項政策指定使用後端 API (Google 的 Geocoding API) 時所需的要求資訊,另一項政策則實際將要求傳送至後端 API。接著,我們會處理回應。

使用 ExtractVariables 剖析回應

ExtractVariables 政策提供簡單的機制,可剖析 ServiceCallout 政策取得的回應訊息內容。ExtractVariables 可用於剖析 JSON 或 XML,或從 URI 路徑、HTTP 標頭、查詢參數和表單參數中擷取內容。

以下列出 ExtractVariables 政策。如要進一步瞭解這項政策,請參閱「擷取變數」政策。在下載的範例中,您可以在 doc-samples/policy-mashup-cookbook/apiproxy/policies/ParseGeocodingResponse.xml 檔案中找到這個 XML。

<ExtractVariables name="ParseGeocodingResponse">
  <Source>GeocodingResponse</Source>
  <VariablePrefix>geocoderesponse</VariablePrefix>
  <JSONPayload>
    <Variable name="latitude">
       <JSONPath>$.results[0].geometry.location.lat</JSONPath>
    </Variable>
    <Variable name="longitude">
       <JSONPath>$.results[0].geometry.location.lng</JSONPath>
    </Variable>
  </JSONPayload>
</ExtractVariables>

ExtractVariable 政策的主要元素包括:

  • <ExtractVariables name> - 同樣地,政策名稱用於在流程中使用政策時參照政策。
  • <Source> - 指定在 ServiceCallout 政策中建立的回應變數。這項政策會從這個變數擷取資料。
  • <VariablePrefix> - 變數前置字元會為這項政策中建立的其他變數指定命名空間。前置字串可以是任何名稱,但不能是 Edge 預先定義變數定義的保留名稱。
  • <JSONPayload>:這個元素會擷取我們感興趣的回應資料,並將其放入具名變數。事實上,Geocoding API 傳回的資訊遠不只經緯度。不過,這些是這個範例唯一需要的值。如要查看 Geocoding API 傳回的完整 JSON 轉譯內容,請參閱 API 說明文件。geometry.location.lat 和 geometry.location.lng 的值只是傳回 JSON 物件中的眾多欄位之二。

這可能不明顯,但請務必瞭解 ExtractVariables 會產生兩個變數,其名稱由變數前置字串 (geocoderesponse) 和政策中指定的實際變數名稱組成。這些變數會儲存在 API Proxy 中,並可供 Proxy 流程中的其他政策使用,詳情請見下文。變數如下:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

現在大部分的工作都已完成。我們建立了一個由三項政策組成的複合政策,用於形成要求、呼叫後端 API,以及剖析傳回的 JSON 資料。在最後的步驟中,我們會將流程這個部分的資料饋送至另一個 AssignMessage 政策,呼叫第二個後端 API (Google Elevation API),並將混搭資料傳回給應用程式開發人員。

使用 AssignMessage 產生第二個要求

下列 AssignMessage 政策會使用我們儲存的第一個後端 (Google Geocoding) 傳回的變數,並將這些變數插入傳送至第二個 API (Google Elevation) 的要求。如先前所述,這些變數是 geocoderesponse.latitude 和 geocoderesponse.longitude。

在下載的範例中,您可以在 doc-samples/policy-mashup-cookbook/apiproxy/policies/AssignElevationParameters.xml 檔案中找到這個 XML。

<AssignMessage name="AssignElevationParameters">
<Remove>
    <QueryParams>
      <QueryParam name="country"/>
      <QueryParam name="postalcode"/>
    </QueryParams>
  </Remove>
  <Set>
    <QueryParams>
      <QueryParam name="locations">{geocoderesponse.latitude},{geocoderesponse.longitude}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
  </Set>
</AssignMessage>

如果您檢查 Google Elevation API,會發現該 API 採用兩個查詢參數。 第一個稱為 locations,值為緯度和經度 (以半形逗號分隔)。另一個參數是 sensor,這是必要參數,且必須為 true 或 false。此時最重要的一點是,我們在這裡建立的要求訊息不需要 ServiceCallout。此時我們不需要從 ServiceCallout 呼叫第二個 API,因為可以從 Proxy 的 TargetEndpoint 呼叫後端 API。仔細想想,我們已經擁有呼叫 Google Elevations API 所需的所有資料。在這個步驟中產生的要求訊息不需要 ServiceCallout,因為這是為主要要求管道產生的要求,因此 ProxyEndpoint 會按照為這個 API Proxy 設定的 RouteRule,將要求轉送至 TargetEndpoint。TargetEndpoint 會管理與遠端 API 的連線。(請注意,高程 API 的網址是在 TargetEndpoint 的 HTTPConnection 中定義。如要瞭解詳情,請參閱 Elevation API 說明文件。我們不再需要先前儲存的 QueryParams (countrypostalcode),因此在此處移除。

短暫停頓:返回流程

此時您可能會想,為什麼我們不建立另一個 ServiceCallout 政策。畢竟我們又建立了一則訊息。該訊息如何傳送至目標 Google Elevation API?答案就在流程的 <RouteRule> 元素中。<RouteRule> 指定在流程的 <Request> 部分執行後,如何處理任何剩餘的要求訊息。這個 <RouteRule> 指定的 TargetEndpoint 會告知 API Proxy 將訊息傳送至 http://maps.googleapis.com/maps/api/elevation/xml

如果您已下載範例 API Proxy,可以在 doc-samples/policy-mashup-cookbook/apiproxy/targets/default.xml 檔案中找到 TargetProxy XML。

<TargetEndpoint name="default">
  <HTTPTargetConnection>
    <!-- This is where we define the target. For this sample we just use a simple URL. -->
    <URL>http://maps.googleapis.com/maps/api/elevation/xml</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

現在,我們只需要處理 Google Elevation API 的回應,就大功告成了。

將 XML 格式的回應轉換為 JSON

在本範例中,Google Elevation API 的回應會以 XML 格式傳回。針對「額外點數」,我們在複合政策中再新增一項政策,將 XML 回應轉換為 JSON。

這個範例使用名為 GenerateResponse 的 JavaScript 政策,以及包含 JavaScript 程式碼的資源檔案,執行轉換作業。GenerateResponse 政策定義如下所示:

<Javascript name="GenerateResponse" timeout="10000">
  <ResourceURL>jsc://GenerateResponse.js</ResourceURL>
</Javascript>

GenerateResponse.js 資源檔案包含用於執行轉換的 JavaScript。您可以在 doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js 檔案中查看該程式碼。

Apigee 也提供 XMLToJSON 這項現成政策,可將 XML 轉換為 JSON。您可以編輯 ProxyEndpoint,改用下列 xmltojson 政策。

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

測試範例

如果尚未完成,請嘗試下載、部署及執行 policy-mashup-cookbook 範例,您可以在 Apigee Edge 範例存放區 GitHub 的 doc-samples 資料夾中找到該範例。只要按照 policy-mashup-cookbook 資料夾中 README 檔案的指示操作即可。或者,請按照使用範例 API Proxy 中的簡短說明操作。

總而言之,您可以按照下列方式呼叫複合 API。將 {myorg} 替換為貴機構名稱:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

回應內容包括應用程式使用者提供的郵遞區號中心點地理編碼位置,以及該地理編碼位置的海拔高度。資料是從兩個後端 API 擷取,並與附加至 API Proxy 的政策混搭,然後以單一回應傳回給用戶端。

{  
   "country":"us",
   "postalcode":"08008",
   "elevation":{  
      "meters":0.5045232,
      "feet":1.6552599030345978
   },
   "location":{  
      "latitude":39.75007129999999,
      "longitude":-74.1357407
   }
}

摘要

本食譜主題說明如何使用政策組合模式,從多個後端來源建立資料混搭。政策組合是 API 代理程式開發中常用的模式,可為 API 新增創意功能。