Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X. Информация
В этой статье рассказывается, как создать мэшап с помощью композиции правил. Композиция правил – это шаблон прокси Apigee, который позволяет объединять результаты из нескольких целевых серверов в единый ответ с помощью правил.
Общие сведения о композиции правил приведены в разделе "Шаблон композиции правил" статьи Шаблоны API-прокси.
Скачайте и попробуйте образец кода
Пример кулинарной книги
В этом примере из справочного руководства показан шаблон прокси-сервера API, который называется композицией правил. Этот шаблон позволяет объединять данные из нескольких источников на стороне сервера. В целом этот раздел показывает, как можно комбинировать правила, чтобы получить нужный результат. Общую информацию об этом и других шаблонах можно найти в сборнике шаблонов прокси API.
В примере, который мы рассмотрим, используется композиция правил для объединения данных из двух отдельных общедоступных API:
- Google Geocoding API. Этот API преобразует адреса (например, "1600 Amphitheatre Parkway, Mountain View, CA") в географические координаты (например, широта 37,423021 и долгота -122,083739).
- Google Elevation API – простой интерфейс для запроса данных о высоте над уровнем моря для разных точек земной поверхности. В этом примере координаты, полученные от Geocoding 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.
Прежде чем изучать пример из этого руководства, ознакомьтесь с основными понятиями:
- Что такое правила и как прикрепить их к прокси. Чтобы узнать больше о правилах, прочитайте статью Что такое правила?
- Структура потока прокси-сервера 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>. Эти шаги также вызывают правила, которые отвечают за обработку конечного ответа от целевой конечной точки (Google Elevation API).
- <HttpProxyConnection> – этот элемент содержит сведения о том, как приложения будут подключаться к прокси-серверу API, в том числе элемент <BasePath>, который указывает, как будет вызываться этот API.
- <RouteRule> – этот элемент определяет, что происходит сразу после обработки входящих запросов. В этом случае вызывается TargetEndpoint. Мы подробнее поговорим об этом важном шаге позже.
Создание правил
В следующих разделах рассматриваются правила, которые входят в этот пример.
Создайте первое правило AssignMessage
Первое правило AssignMessage, перечисленное ниже, создает запрос, который будет отправлен в сервис Geocoding от 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>
Ниже приведено краткое описание элементов этих правил. Подробнее о правилах в отношении сообщений, назначаемых пользователям…
- <AssignMessage name> – позволяет задать название для этих правил. Это название используется, когда на правило ссылаются в процессе.
- <AssignTo> – создает именованную переменную GeocodingRequest. Эта переменная содержит объект запроса, который будет отправлен на серверную часть правилом ServiceCallout.
- <QueryParams> – задает параметры запроса, необходимые для вызова API на сервере. В этом случае Geocoding API должен знать местоположение, которое выражается почтовым индексом и идентификатором страны. Пользователь приложения предоставляет эту информацию, а мы просто извлекаем ее. Параметр
sensorобязателен для API и может иметь значение true или false. В нашем случае он имеет значение false. - <Verb> – в этом случае мы отправляем простой 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> – как и в предыдущих правилах, у этого есть название.
- <Request variable> – переменная, созданная в правиле AssignMessage. Он содержит запрос, отправляемый в API внутреннего сервиса.
- <Response> – элемент, в котором указывается переменная, в которой хранится ответ. Как вы увидите, эта переменная будет позже использоваться правилом ExtractVariables.
- <HTTPTargetConnection> – указывает целевой URL внутреннего API. В этом случае мы указываем, что API должен вернуть ответ JSON.
Теперь у нас есть два правила: одно указывает, какая информация нужна для использования внутреннего API (Geocoding 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:
- <ExtractVariables name> – название политики используется для ссылки на нее в потоке.
- <Source> – указывает переменную ответа, созданную в правиле ServiceCallout. Это переменная, из которой извлекаются данные.
- <VariablePrefix> – префикс переменной задает пространство имен для других переменных, созданных в этой политике. Префикс может быть любым именем, кроме зарезервированных имен, определенных стандартными переменными Edge.
- <JSONPayload> – этот элемент извлекает из ответа нужные нам данные и помещает их в именованные переменные. На самом деле Geocoding API возвращает гораздо больше информации, чем широта и долгота. Однако для этого примера нам нужны только эти значения. Полный текст ответа JSON, возвращаемого Geocoding 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>Если вы изучите Google Elevation API, то увидите, что он принимает два параметра запроса.
Первый называется locations, а его значение – широта и долгота (значения разделены запятыми). Другой параметр – sensor. Он обязателен и должен иметь значение true или false. Важно отметить, что созданный здесь запрос не требует ServiceCallout. На этом этапе нам не нужно вызывать второй API из ServiceCallout, поскольку мы можем вызвать внутренний API из TargetEndpoint прокси. Если подумать, у нас есть все необходимые данные для вызова Google Elevations API. Запрос, созданный на этом этапе, не требует ServiceCallout, поскольку он был создан для основного конвейера запросов и будет просто перенаправлен ProxyEndpoint в TargetEndpoint в соответствии с RouteRule, настроенным для этого прокси-сервера API.
TargetEndpoint управляет подключением к удаленному API. (Напомним, что URL для Elevation API задан в HTTPConnection для TargetEndpoint. Elevation API. Параметры QueryParams, которые мы сохранили ранее (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>
Теперь нам нужно обработать ответ от Google Elevation API.
Преобразовать ответ из XML в JSON.
В этом примере ответ от Google Elevation API возвращается в формате 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 новых функций.