Использование композиции политики

Вы просматриваете документацию Apigee Edge .
Перейдите в документацию Apigee
X.info

В этой теме вы узнаете, как создать мэшап с использованием композиции политик . Композиция политик — это шаблон прокси Apigee, который позволяет объединять результаты из нескольких целевых серверов в один ответ с помощью политик.

Общий обзор структуры политик см. в разделе «Шаблон структуры политик» в руководстве по шаблонам API Proxy Cookbook .

Скачайте и попробуйте пример кода.

Об этом примере кулинарной книги

Этот пример из сборника рецептов иллюстрирует шаблон API-прокси, называемый композицией политик . Этот шаблон предоставляет один из способов (существуют и другие) объединения данных из нескольких источников бэкэнда. В более общем плане, эта тема демонстрирует, как политики можно комбинировать и связывать вместе для получения желаемого результата. Для общего обзора этого шаблона и других связанных с ним шаблонов см. раздел «Шаблоны API-прокси из сборников рецептов» .

В рассматриваемом здесь примере используется композиция политик для объединения данных из двух отдельных общедоступных API:

  • API геокодирования Google : Этот API преобразует адреса (например, "1600 Amphitheatre Parkway, Mountain View, CA") в географические координаты (например, широта 37.423021 и долгота -122.083739).
  • API Google Elevation. Этот API предоставляет простой интерфейс для запроса данных о высоте местоположения на Земле. В этом примере координаты, возвращаемые API геокодирования, будут использоваться в качестве входных данных для этого API.

Разработчики приложений будут вызывать этот API-прокси с двумя параметрами запроса: почтовым индексом и идентификатором страны:

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

Прежде чем приступить к изучению этого примера из кулинарной книги, вам также следует ознакомиться со следующими основными понятиями:

  • Что такое политика и как её применять к доверенностям. Для ознакомления с понятием политики см. статью «Что такое политика?» .
  • Структура потока API-прокси, как описано в разделе «Настройка потоков» . Потоки позволяют указать последовательность выполнения политик API-прокси. В этом примере создается и добавляется несколько политик в поток API-прокси.
  • Как организован проект API-прокси в вашей файловой системе, как объясняется в справочнике по настройке API-прокси . В этом разделе руководства показана локальная разработка (на основе файловой системы) в отличие от облачной разработки, где вы могли бы использовать пользовательский интерфейс управления для разработки API-прокси.
  • Использование проверки ключей API. Это простейшая форма безопасности на уровне приложения, которую можно настроить для API. Для получения дополнительной информации см. раздел «Ключи API» . Вы также можете ознакомиться с руководством по обеспечению безопасности API путем обязательного использования ключей API .
  • Необходимо иметь практические знания XML. В этом примере мы создаём API-прокси и его политики с помощью XML-файлов, расположенных в файловой системе.

Если вы скачали пример кода, все файлы, обсуждаемые в этой теме, находятся в папке mashup-policy-cookbook . В следующих разделах пример кода рассматривается подробно.

Плыть по течению

Прежде чем перейти к политикам, давайте рассмотрим основной поток нашего примера API-прокси. XML-код потока, показанный ниже, многое говорит нам об этом прокси, используемых им политиках и местах вызова этих политик.

В загруженном образце вы найдете этот XML-код в файле doc-samples/policy-mashup-cookbook/apiproxy/proxies/default.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>. Эти шаги также вызывают политики, отвечающие за обработку окончательного ответа от целевой конечной точки (API Google Elevation).
  • <HttpProxyConnection> — Этот элемент определяет подробности о том, как приложения будут подключаться к этому API-прокси, включая <BasePath>, который указывает, как будет вызываться этот API.
  • <RouteRule> — Этот элемент определяет, что происходит сразу после обработки входящих запросов. В данном случае вызывается TargetEndpoint. Подробнее об этом важном шаге мы поговорим позже в этой теме.

Разработка политики

В следующих разделах рассматривается каждая из политик, входящих в данный пример структуры политики.

Создайте первую политику AssignMessage.

Первая политика AssignMessage , указанная ниже, создает сообщение-запрос, которое будет отправлено в службу геокодирования Google.

Начнём с кода политики, а затем более подробно рассмотрим его элементы. В загруженном примере вы найдёте этот XML-код в файле doc-samples/policy-mashup-cookbook/apiproxy/policies/GenerateGeocodingRequest.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>

Ниже приведено краткое описание элементов этой политики. Более подробную информацию об этой политике можно найти в разделе «Политика назначения сообщений» .

  • <Имя присваиваемого сообщения> - Задает имя этой политике. Имя используется, когда политика используется в потоке.
  • <AssignTo> - Создает именованную переменную с именем GeocodingRequest. Эта переменная инкапсулирует объект запроса, который будет отправлен на серверную часть политикой ServiceCallout.
  • <QueryParams> — Задает параметры запроса, необходимые для вызова API бэкэнда. В данном случае API геокодирования необходимо знать местоположение, которое выражается почтовым индексом и идентификатором страны. Пользователь приложения предоставляет эту информацию, и мы просто извлекаем ее здесь. Параметр sensor является обязательным для API и может принимать значения true или false, поэтому мы просто задаем его значение false.
  • <Глагол> - В данном случае мы выполняем простой GET-запрос к API.
  • <AssignVariable> — Эти переменные хранят значения, которые мы передаем в API. В этом примере доступ к переменным будет осуществлен позже в ответе, возвращаемом клиенту.

Отправьте запрос с помощью ServiceCallout.

Следующим шагом в последовательности создания политик является создание политики ServiceCallout . Политика ServiceCallout, приведенная ниже, отправляет объект запроса, созданный нами в предыдущей политике AssignMessage, в службу геокодирования Google и сохраняет результат в переменной с именем GeocodingResponse.

Как и прежде, давайте сначала посмотрим на код. Подробное объяснение приведено ниже. Вы можете узнать больше об этой политике в разделе «Политика вызова сервиса» . В загруженном примере вы найдете этот XML-код в файле doc-samples/policy-mashup-cookbook/apiproxy/policies/ExecuteGeocodingRequest.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> — указывает целевой URL-адрес бэкэнд-API. В данном случае мы указываем, что API должен возвращать JSON-ответ.

Теперь у нас есть две политики: одна определяет информацию запроса, необходимую для использования бэкэнд-API (API геокодирования Google), а вторая фактически отправляет запрос в бэкэнд-API. Далее мы обработаем ответ.

Проанализируйте ответ с помощью функции ExtractVariables.

Политика ExtractVariables предоставляет простой механизм для анализа содержимого ответного сообщения, полученного с помощью политики ServiceCallout. ExtractVariables можно использовать для анализа JSON или XML, а также для извлечения содержимого из URI-путей, HTTP-заголовков, параметров запроса и параметров формы.

Ниже представлен список параметров политики ExtractVariables. Подробнее об этой политике можно прочитать в разделе «Политика извлечения переменных» . В загруженном примере вы найдете этот XML-код в файле doc-samples/policy-mashup-cookbook/apiproxy/policies/ParseGeocodingResponse.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:

  • <Имя извлекаемых переменных> - Опять же, имя политики используется для ссылки на политику при ее использовании в потоке.
  • <Источник> - Указывает переменную ответа, которую мы создали в политике ServiceCallout. Именно из этой переменной данная политика извлекает данные.
  • <VariablePrefix> - Префикс переменной задает пространство имен для других переменных, созданных в этой политике. Префикс может быть любым именем, за исключением зарезервированных имен, определенных предопределенными переменными Edge .
  • <JSONPayload> — Этот элемент извлекает интересующие нас данные ответа и помещает их в именованные переменные. На самом деле, API геокодирования возвращает гораздо больше информации, чем широта и долгота. Однако для этого примера нам нужны только эти значения. Полное отображение JSON-данных, возвращаемых API геокодирования, можно увидеть в документации API . Значения geometry.location.lat и geometry.location.lng — это лишь два из множества полей в возвращаемом JSON-объекте.

Возможно, это не очевидно, но важно понимать, что ExtractVariables создает две переменные, имена которых состоят из префикса переменной (geocoderesponse) и фактических имен переменных, указанных в политике. Эти переменные хранятся в API-прокси и будут доступны другим политикам в рамках потока прокси, как вы увидите далее. Переменные следующие:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

Большая часть работы уже выполнена. Мы создали комбинацию из трех политик, которые формируют запрос, вызывают бэкэнд-API и анализируют возвращаемые данные в формате JSON. На заключительных этапах мы передадим данные из этой части потока в другую политику AssignMessage, вызовем второй бэкэнд-API (Google Elevation API) и вернем наши объединенные данные разработчику приложения.

Сгенерируйте второй запрос с помощью AssignMessage.

Следующая политика AssignMessage использует переменные, возвращенные из первого бэкэнда (Google Geocoding), которые мы сохранили, и подставляет их в запрос, предназначенный для второго API (Google Elevation). Как отмечалось ранее, этими переменными являются geocoderesponse.latitude и geocoderesponse.longitude.

В загруженном образце вы найдете этот XML-код в файле doc-samples/policy-mashup-cookbook/apiproxy/policies/AssignElevationParameters.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>

Если вы изучите API Google Elevation, вы увидите, что он принимает два параметра запроса. Первый называется locations , и его значение — широта и долгота (значения, разделенные запятыми). Другой параметр — sensor , который является обязательным и должен быть либо true, либо false. Самое важное, что следует отметить на этом этапе, — это то, что создаваемое нами сообщение запроса не требует вызова ServiceCallout. Нам не нужно вызывать второй API из ServiceCallout на данном этапе, потому что мы можем вызвать бэкэнд-API из TargetEndpoint прокси-сервера. Если подумать, у нас есть все необходимые данные для вызова API Google Elevation. Сообщение запроса, сгенерированное на этом шаге, не требует вызова ServiceCallout, поскольку запрос генерируется для основного конвейера запросов, и поэтому будет просто перенаправлен ProxyEndpoint в TargetEndpoint в соответствии с правилом маршрутизации, настроенным для этого API-прокси. TargetEndpoint управляет соединением с удаленным API. (Напомним, что URL-адрес для API повышения высоты определяется в HTTPConnection для TargetEndpoint. Дополнительную информацию можно найти в документации API повышения высоты. Параметры запроса, которые мы хранили ранее, country и postalcode , больше не нужны, поэтому мы удаляем их здесь.)

Небольшая пауза: Возвращаемся к прежнему ритму.

На этом этапе вы можете задаться вопросом, почему мы не создаем еще одну политику ServiceCallout. В конце концов, мы создали еще одно сообщение. Как это сообщение отправляется целевому объекту, Google Elevation API? Ответ кроется в элементе <RouteRule> потока. <RouteRule> определяет, что делать с любыми оставшимися запросами после выполнения части потока <Request>. TargetEndpoint, указанный в этом <RouteRule>, сообщает прокси-серверу API о необходимости доставить сообщение по адресу http://maps.googleapis.com/maps/api/elevation/xml .

Если вы скачали пример API-прокси, вы найдете XML-файл TargetProxy в файле doc-samples/policy-mashup-cookbook/apiproxy/targets/default.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>

Теперь нам осталось только обработать ответ от API Google Elevation, и всё готово.

Преобразовать ответ из XML в JSON.

В этом примере ответ от API Google Elevation возвращается в формате XML. В качестве дополнительного задания добавим еще одну политику в наш составной объект, чтобы преобразовать ответ из XML в JSON.

В этом примере используется политика JavaScript с именем GenerateResponse, содержащая файл ресурсов с кодом 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 , который находится в папке doc-samples в репозитории примеров Apigee Edge на GitHub. Просто следуйте инструкциям в файле README в папке policy-mashup-cookbook. Или следуйте кратким инструкциям здесь: Использование примеров API-прокси .

Вкратце, вы можете вызвать составной API следующим образом. Замените {myorg} на название вашей организации:

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

В ответе содержится геолокационное местоположение центра почтового индекса, предоставленное конечным пользователем приложения, в сочетании с высотой над уровнем моря в этом геолокационном месте. Данные были получены из двух бэкэнд-API, объединены с политиками, прикрепленными к прокси-серверу API, и возвращены клиенту в одном ответе.

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

Краткое содержание

В этом разделе руководства объясняется, как использовать шаблон композиции политик для создания объединения данных из нескольких источников на стороне бэкэнда. Композиция политик — это распространенный шаблон, используемый в разработке API-прокси для добавления нестандартной функциональности к вашему API.