使用政策組合

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

在本主題中,您將瞭解如何使用政策組合建立混搭功能。政策組合是一種 Apigee Proxy 模式,可讓您使用政策,將多個後端目標的結果合併為單一回應。

如需政策組合的一般總覽,請參閱 API Proxy 教戰手冊模式中的「政策組成模式」。

下載並試用程式碼範例

關於這個食譜集範例

本教戰手冊範例說明稱為「政策組成」的 API Proxy 模式。這個模式提供一種方式 (還有其他方式) 來混合多個後端來源的資料。更廣泛來說,本主題示範如何結合政策並鏈結在一起,藉此產生想要的結果。如需這種模式和其他相關項目的概要總覽,請參閱 API Proxy 教戰手冊模式

本文討論的範例會使用政策組合,將以下兩個不同公用 API 的資料混搭:

  • Google Geocoding API:這個 API 會將地址 (例如「1600 Amphitheatre Parkway, Mountain View, CA」) 轉換為地理座標 (例如緯度 37.423021 和經度 -122.083739)。
  • Google Elevation 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 教戰手冊模式中的「政策組合模式」。

探索這個教戰手冊範例之前,建議您也熟悉下列基本概念:

  • 何謂政策,以及如何將政策附加至 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、該 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 (包括指定呼叫這個 API 的 <BasePath>) 的詳細資料。
  • <RouteRule>:這個元素會指定處理傳入要求訊息後立即執行的操作,在此情況下,系統會呼叫 TargetEndpoint。本主題稍後將進一步說明這個重要步驟。

建立政策

以下各節將說明組成這個政策組合範例的每項政策。

建立第一項 AssignMessage 政策

下列第一項 AssignMessage 政策 (如下所列) 建立要求訊息並傳送至 Google 地理編碼服務。

首先,我們先從政策程式碼開始,這時候會詳細說明其中的元素。在下載範例中,您可以在 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。這個變數會封裝由 Service Call 政策傳送至後端的要求物件。
  • <QueryParams>:設定後端 API 呼叫所需的查詢參數。在此情況下,Geocoding API 必須知道地點 (以郵遞區號和國家/地區 ID 表示)。應用程式使用者提供了這項資訊,而我們只需在此處擷取這些資訊。sensor 是 API 的必要參數,且為 true 或 false,而我們在這裡用硬式編碼的方式設為 false。
  • <Verb>:在這個案例中,我們會向 API 發出簡單的 GET 要求。
  • <AssignVariable>:這些變數會儲存傳遞給 API 的值。在本範例中,稍後可在傳回用戶端的回應中存取變數。

使用 Service Call 傳送要求

政策組成序列的下一步是建立 ServiceCallout 政策。Service 呼叫政策 (如下所示) 會將我們在先前 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> - 跟前一個政策一樣,這項政策有名稱。
  • <RequestVariable> - 這是在 AssignMessage 政策中建立的變數。這會封裝傳送至後端 API 的要求。
  • <Response> - 此元素會為儲存回應的變數命名。如畫面所示,您之後可以透過「擷取變數」政策存取這個變數。
  • <HTTPTargetConnection>:指定後端 API 的目標網址。在本例中,我們指定 API 傳回 JSON 回應。

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

使用 ExtractVariables 剖析回應

擷取變數政策提供簡單的機制,可讓您剖析服務呼叫政策取得的回應訊息內容。「擷取變數」可用來剖析 JSON 或 XML,或是從 URI 路徑、HTTP 標頭、查詢參數和表單參數中擷取內容。

以下是「擷取變數」政策的清單。如要進一步瞭解這項政策,請參閱「擷取變數政策」一文。在下載範例中,您可以在 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> - 指定我們在 Service 呼叫政策中建立的回應變數。這是這項政策用來擷取資料的變數。
  • <VariablePrefix>:變數前置字串會為這項政策中建立的其他變數指定命名空間。前置字串可以是任何名稱,但 Edge 的預先定義變數定義的保留名稱除外。
  • <JSONPayload> - 這個元素會擷取我們感興趣的回應資料,並將資料放入具名變數。事實上,Geocoding API 傳回的資訊比經緯度遠多。不過,這個範例唯一需要的值。您可以在 API 說明文件中,查看 Geocoding API 傳回的 JSON 完整轉譯內容。幾何圖形.location.lat 和 幾何圖形.location.lng 的值只是傳回的 JSON 物件中的兩個欄位之一。

可能並不明顯,但請務必注意,ExtractVariables 會產生兩個變數的名稱,其名稱包含變數前置字元 (地理編碼回應) 和政策中指定的實際變數名稱。這些變數會儲存在 API Proxy 中,如畫面所示,適用於 Proxy 流程中的其他政策。變數包括:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

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

使用 AssignMessage 產生第二個要求

下列 AssignMessage 政策使用我們儲存的第一個後端 (Google Geocoding) 傳回的變數,並將其插入目的地為第二個 API (Google Elevation) 的要求。如前所述,這些變數是 地理編碼回應.latitude 和 Geocoding 回應.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」。此時要特別注意的是,此處建立的要求訊息不需要服務呼叫。在這個階段,我們不需要從 Service Call 呼叫第二個 API,因為可以透過 Proxy 的 TargetEndpoint,呼叫後端 API。想想看,我們擁有呼叫 Google Elevations API 所需的所有資料。這個步驟產生的要求訊息不需要 Service 呼叫 (因為為主要要求管道產生的要求),因此只要 Proxy 端點按照您為這個 API Proxy 設定的 RouteRule 就可以轉送到 TargetEndpoint。TargetEndpoint 會管理與遠端 API 的連線。(提醒您,elevation API 的網址是在 TargetEndpoint 的 HTTPConnection 中定義。Elevation API 說明文件。我們先前儲存的 QueryParams (countrypostalcode) 已不再需要,所以我們會在這裡移除。

短暫暫停:返回流程

您可能會好奇,為何我們不建立另一個 Service 稱 政策。畢竟,我們又建立了新的訊息。這樣訊息如何傳送到目標 (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 Proxy 開發時常用的模式,用於在 API 中新增廣告素材功能。