Вы просматриваете документацию по Apigee Edge.
Перейдите к документации по Apigee X. Информация
Что
Правило Service Callout позволяет вызывать другой сервис из потока прокси-сервера API. Вы можете отправлять запросы как к внешним сервисам (например, к конечной точке внешнего сервиса RESTful), так и к внутренним сервисам (например, к прокси-серверу API в той же организации и среде).
- В случае внешнего использования вы вызываете сторонний API, который находится за пределами вашего прокси-сервера. Ответ от стороннего API анализируется и вставляется в ответное сообщение вашего API, обогащая и объединяя данные для конечных пользователей приложения. Вы также можете отправить запрос, используя правило Service Callout в потоке запроса, а затем передать информацию в ответе в TargetEndpoint прокси-сервера API.
- В другом случае вы звоните на прокси, который находится в той же организации и среде, что и тот, с которого вы звоните. Например, это может быть полезно, если у вас есть прокси, который предлагает некоторые отдельные низкоуровневые функции, используемые одним или несколькими другими прокси. Например, прокси-сервер, который предоставляет операции создания, чтения, обновления и удаления с хранилищем данных на сервере, может быть целевым прокси-сервером для нескольких других прокси-серверов, которые предоставляют данные клиентам.
Правило поддерживает запросы по протоколам HTTP и HTTPS.
Примеры
Локальный вызов на внутренний прокси-сервер
<LocalTargetConnection>
<APIProxy>data-manager</APIProxy>
<ProxyEndpoint>default</ProxyEndpoint>
</LocalTargetConnection>В этом примере создается вызов локального прокси-сервера API (то есть прокси-сервера в той же организации и среде) с названием data-manager, указывается его конечная точка прокси с названием default.
URL как переменная
<HTTPTargetConnection>
<URL>http://example.com/{request.myResourcePath}</URL>
</HTTPTargetConnection>В этом примере в URL используется переменная, которая динамически заполняет URL целевой страницы. Протокол URL, http://, нельзя задать с помощью переменной. Кроме того, необходимо использовать отдельные переменные для доменной части URL и для остальной части URL.
Запрос на геокодирование или определение от Google
<ServiceCallout name="ServiceCallout-GeocodingRequest1"> <DisplayName>Inline request message</DisplayName> <Request variable="authenticationRequest"> <Set> <QueryParams> <QueryParam name="address">{request.queryparam.postalcode}</QueryParam> <QueryParam name="region">{request.queryparam.country}</QueryParam> <QueryParam name="sensor">false</QueryParam> </QueryParams> </Set> </Request> <Response>GeocodingResponse</Response> <Timeout>30000</Timeout> <HTTPTargetConnection> <URL>http://maps.googleapis.com/maps/api/geocode/json</URL> </HTTPTargetConnection> </ServiceCallout>
http://maps.googleapis.com/maps/api/geocode/json
Вместо того чтобы использовать правило, например Assign Message, для создания объекта запроса, вы можете определить его непосредственно в правиле вызова сервиса. В этом примере политика вызова сервиса задает значения трех параметров запроса, передаваемых внешнему сервису. Вы можете создать сообщение запроса целиком в правиле Service Callout, указав полезную нагрузку, тип кодировки, например application/xml, заголовки, параметры формы и т. д.
Вот ещё один пример, в котором запрос формируется до того, как будет достигнуто правило "Выноска с предложением услуг".
<ServiceCallout name="ServiceCallout-GeocodingRequest2"> <Request clearPayload="false" variable="GeocodingRequest"/> <Response>GeocodingResponse</Response> <Timeout>30000</Timeout> <HTTPTargetConnection> <URL>http://maps.googleapis.com/maps/api/geocode/json</URL> </HTTPTargetConnection> </ServiceCallout>
Содержимое запроса извлекается из переменной GeocodingRequest (которая может быть заполнена, например, правилом AssignMessage). Сообщение ответа присваивается переменной GeocodingResponse, где оно доступно для анализа с помощью правила извлечения переменных или пользовательского кода, написанного на JavaScript или Java. Правило ожидает ответа от Google Geocoding API в течение 30 секунд, после чего время ожидания истекает.
Полный пример прокси-сервера API, в котором используется этот пример вызова сервиса, а также правила Assign Message и Extract Variables, приведен в разделе Использование композиции правил.
Серверы целевых звонков
<ServiceCallout async="false" continueOnError="false" enabled="true" name="service-callout"> <DisplayName>service-callout</DisplayName> <Properties/> <Request clearPayload="true" variable="myRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </Request> <Response>myResponse</Response> <HTTPTargetConnection> <LoadBalancer> <Algorithm>RoundRobin</Algorithm> <Server name="httpbin"/> <Server name="yahoo"/> </LoadBalancer> <Path>/get</Path> </HTTPTargetConnection> </ServiceCallout>
Эта политика использует атрибут LoadBalancer для вызова целевых серверов и балансировки нагрузки между ними. В этом примере нагрузка распределяется между двумя целевыми серверами с именами httpbin и yahoo. Информацию о том, как настроить целевые серверы для прокси-сервера и сбалансировать нагрузку, можно найти в статье Балансировка нагрузки между внутренними серверами.
Правила в отношении уведомлений о сервисах
Правило Service Callout можно использовать в прокси-сервере API в разных ситуациях. Например, вы можете настроить прокси-сервер API для вызова внешнего сервиса, чтобы получать данные геолокации, отзывы клиентов, товары из каталога партнера и т. д.
Вызов обычно используется с двумя другими правилами: "Назначить сообщение" и "Извлечь переменные".
- Запрос. Функция "Назначить сообщение" заполняет сообщение запроса, отправленное удаленному сервису.
-
Ответ. Функция "Извлечь переменные" анализирует ответ и извлекает определенный контент.
Обычно правила для описаний услуг состоят из следующих элементов:
- Назначить правило для сообщения. Создает сообщение запроса, заполняет HTTP-заголовки, параметры запроса, задает HTTP-метод и т. д.
- Правило Вызов сервиса ссылается на сообщение, созданное правилом "Назначить сообщение", определяет целевой URL для внешнего вызова и задает название объекта ответа, который возвращает целевой сервис.
Чтобы повысить производительность, вы также можете кешировать ответы Service Callout, как описано в этой теме на форуме сообщества Apigee: Как сохранить результаты правила ServiceCallout в кеше и позже извлечь их из кеша?. - Извлечение переменных policy обычно определяет выражение JSONPath или XPath, которое анализирует сообщение, сгенерированное вызовом сервиса. Затем правило задает переменные, содержащие значения, полученные из ответа вызова сервиса.
Полный пример прокси-сервера API, в котором используется правило вызова сервиса вместе с правилами назначения сообщения и извлечения переменных, приведен в разделе Использование композиции правил.
Собственная обработка ошибок
Сведения об элементах
Ниже перечислены элементы и атрибуты, которые можно настроить в этом правиле:
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1"> <DisplayName>Custom label used in UI</DisplayName> <Request clearPayload="true" variable="myRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <Remove> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Remove> <Copy> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Copy> <Add> <Headers/> <QueryParams/> <FormParams/> </Add> <Set> <Headers/> <QueryParams/> <FormParams/> <Payload/> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Set> </Request> <Response>calloutResponse</Response> <Timeout>30000</Timeout> <HTTPTargetConnection> <URL>http://example.com</URL> <LoadBalancer/> <SSLInfo/> <Properties/> </HTTPTargetConnection> <LocalTargetConnection> <APIProxy/> <ProxyEndpoint/> <Path/> </LocalTargetConnection> </ServiceCallout>
Атрибуты <ServiceCallout>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">
В следующей таблице описаны атрибуты, общие для всех родительских элементов политики:
| Атрибут | Описание | По умолчанию | Присутствие |
|---|---|---|---|
name | Внутреннее имя политики. Значение атрибута При необходимости используйте элемент | Н/Д | Необходимый |
continueOnError | Установите значение Установите значение | ЛОЖЬ | Необязательный |
enabled | Установите значение Установите значение | истинный | Необязательный |
async | Этот атрибут устарел. | ЛОЖЬ | Устарело |
Элемент <DisplayName>
Используйте в дополнение к атрибуту name , чтобы пометить политику в редакторе прокси-сервера пользовательского интерфейса управления другим именем на естественном языке.
<DisplayName>Policy Display Name</DisplayName>
| По умолчанию | Н/Д Если вы опустите этот элемент, будет использовано значение атрибута |
|---|---|
| Присутствие | Необязательный |
| Тип | Нить |
Элемент <Request>
Указывает переменную, содержащую сообщение запроса, которое отправляется из прокси-сервера API в другой сервис. Переменную можно создать с помощью предыдущего правила в потоке или непосредственно в правиле выноски сервиса.
<Request clearPayload="true" variable="myRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <Remove> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Remove> <Copy> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Copy> <Add> <Headers/> <QueryParams/> <FormParams/> </Add> <Set> <Headers/> <QueryParams/> <FormParams/> <Payload/> <ReasonPhrase/> <StatusCode/> <Path/> <Version/> <Verb/> </Set> </Request>
Синтаксис тегов <Remove>, <Copy>, <Add> и <Set> такой же, как и для правила "Назначить сообщение".
Правило возвращает ошибку, если запрос не может быть разрешен или имеет недопустимый тип.
В самом простом случае вы передаете переменную, содержащую сообщение запроса, которое было заполнено ранее в потоке прокси-сервера API:
<Request clearPayload="true" variable="myRequest"/>
Или вы можете заполнить сообщение запроса, отправленное во внешний сервис, в самом правиле вызова сервиса:
<Request> <Set> <Headers> <Header name="Accept">application/json</Header> </Headers> <Verb>POST</Verb> <Payload contentType="application/json">{"message":"my test message"}</Payload> </Set> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </Request>
| По умолчанию | Если вы не укажете элемент Request или какой-либо из его атрибутов, Edge присвоит следующие значения по умолчанию:
<Request clearPayload="true" variable="servicecallout.request"/> Давайте посмотрим, что означают эти значения по умолчанию. Во-первых,
Если вы используете маскировку данных, важно знать это название по умолчанию. Если вы не укажете название переменной, вам нужно будет добавить |
| Присутствие | Необязательное поле. |
| Тип | Н/Д |
Атрибуты
| Атрибут | Описание | По умолчанию | Тип поля |
|---|---|---|---|
| variable |
Название переменной, которая будет содержать сообщение запроса. |
servicecallout.request |
Необязательно |
| clearPayload |
Если задано значение Установите для параметра clearPayload значение false, только если сообщение запроса необходимо после выполнения вызова сервиса. |
true | Необязательно |
Элемент <Request>/<IgnoreUnresolvedVariables>
Если задано значение true, правило игнорирует все ошибки, связанные с неразрешенными переменными в запросе.
<Request clearPayload="true" variable="myRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </Request>
| По умолчанию | false |
| Присутствие | Необязательно |
| Тип | Логическое значение |
Элемент <Response>
Добавьте этот элемент, если логика прокси-сервера API требует ответа от удаленного вызова для дальнейшей обработки.
Если этот элемент присутствует, он указывает название переменной, которая будет содержать сообщение ответа, полученное от внешнего сервиса. Ответ от целевого сервиса присваивается переменной только в том случае, если правило успешно прочитало весь ответ. Если удаленный вызов не удастся по какой-либо причине, правило вернет ошибку.
Если этот элемент опущен, прокси-сервер API не ждет ответа, а выполнение потока прокси-сервера API продолжается со следующими шагами. Кроме того, без элемента Response ответ от целевого объекта не будет доступен для обработки на последующих этапах, и прокси-сервер не сможет обнаружить сбой удаленного вызова.
Обычно элемент Response не используется при работе с ServiceCallout, чтобы регистрировать сообщения во внешней системе.
<Response>calloutResponse</Response>
| По умолчанию | – |
| Присутствие | Необязательно |
| Тип | Строка |
Элемент <Timeout>
Время в миллисекундах, в течение которого правило вызова сервиса будет ждать ответа от целевого сервиса. Это значение нельзя задать динамически во время выполнения. Если вызов сервиса не будет выполнен в течение заданного времени, будет возвращен код HTTP 500, правило не сработает, а прокси API перейдет в состояние ошибки, как описано в разделе Обработка ошибок.
<Timeout>30000</Timeout>
| По умолчанию | 55 000 миллисекунд (55 секунд) – значение времени ожидания HTTP по умолчанию для Apigee Edge. |
| Присутствие | Необязательно |
| Тип | Целое число |
Элемент <HTTPTargetConnection>
Содержит сведения о транспорте, например URL, TLS/SSL и свойства HTTP. Подробнее <TargetEndpoint>…
<HTTPTargetConnection>
<URL>http://example.com</URL>
<LoadBalancer/>
<SSLInfo/>
<Properties/>
</HTTPTargetConnection>| По умолчанию | Н/Д |
| Присутствие | Обязательно |
| Тип | Н/Д |
Элемент <HTTPTargetConnection>/<URL>
URL вызываемого сервиса:
<HTTPTargetConnection>
<URL>http://example.com</URL>
</HTTPTargetConnection>Часть URL можно задать динамически с помощью переменной. Однако протокол в URL (в примере ниже – http://) нельзя задать с помощью переменной. В следующем примере переменная используется для указания значения параметра запроса:
<URL>http://example.com/forecastrss?w=${request.header.woeid}</URL>
Или задайте часть пути URL с помощью переменной:
<URL>http://example.com/{request.resourcePath}?w=${request.header.woeid}</URL>Если вы хотите использовать переменную, чтобы указать домен и порт URL, то используйте одну переменную только для домена и порта, а вторую – для любой другой части URL:
<URL>http://{request.dom_port}/{request.resourcePath}</URL>| По умолчанию | Н/Д |
| Присутствие | Обязательно |
| Тип | Строка |
Элемент <HTTPTargetConnection>/<SSLInfo>
Конфигурация TLS/SSL для бэкенд-службы. Информацию о настройке TLS/SSL можно найти в статьях Настройка TLS от Edge до внутреннего сервера (Cloud и Private Cloud) и "Настройка TargetEndpoint TLS/SSL" в Справочнике по конфигурации прокси API.
<HTTPTargetConnection>
<URL>https://example.com</URL>
<SSLInfo>
<Enabled>true</Enabled>
<ClientAuthEnabled>true</ClientAuthEnabled>
<KeyStore>ref://mykeystoreref</KeyStore> ## Use of a reference is recommended
<KeyAlias>myKey</KeyAlias>
<TrustStore>myTruststore</TrustStore>
<Ciphers/>
<Protocols/>
</SSLInfo>
</HTTPTargetConnection>| По умолчанию | Н/Д |
| Присутствие | Необязательно |
| Тип | Н/Д |
Элемент <HTTPTargetConnection>/<Properties>
Свойства транспорта HTTP для бэкенд-службы. Дополнительную информацию можно найти в разделе Справочник по свойствам конечных точек.
<HTTPTargetConnection>
<URL>http://example.com</URL>
<Properties>
<Property name="allow.http10">true</Property>
<Property name="request.retain.headers">
User-Agent,Referer,Accept-Language
</Property>
</Properties>
</HTTPTargetConnection>| По умолчанию | Н/Д |
| Присутствие | Необязательно |
| Тип | Н/Д |
Элемент <HTTPTargetConnection>/<LoadBalancer>
Вызывать один или несколько целевых серверов и балансировать нагрузку на них. Пример Вызов целевых серверов можно найти в разделе с примерами. Также ознакомьтесь с информацией о балансировке нагрузки между внутренними серверами. Также ознакомьтесь с этой записью в сообществе, где обсуждаются способы вызова целевых серверов с помощью правила вызова сервиса и правил маршрутизации.
<HTTPTargetConnection> <LoadBalancer> <Algorithm>RoundRobin</Algorithm> <Server name="httpbin"/> <Server name="yahoo"/> </LoadBalancer> <Path>/get</Path> </HTTPTargetConnection>
| По умолчанию | Н/Д |
| Присутствие | Необязательно |
| Тип | – |
Элемент <LocalTargetConnection>
Указывает локальный прокси, то есть прокси в той же организации и среде, в качестве цели вызовов сервисов.
Чтобы уточнить цель, используйте элементы <APIProxy> и <ProxyEndpoint> или элемент <Path>.
<LocalTargetConnection> <APIProxy/> <ProxyEndpoint/> <Path/> </LocalTargetConnection>
| По умолчанию | Н/Д |
| Присутствие | Обязательно |
| Тип | Н/Д |
Элемент <LocalTargetConnection>/<APIProxy>
Название прокси-сервера API, который является целью локального вызова. Прокси-сервер должен находиться в той же организации и среде, что и прокси-сервер, выполняющий вызов.
<LocalTargetConnection> <APIProxy>data-manager</APIProxy> <ProxyEndpoint>default</ProxyEndpoint> </LocalTargetConnection>
Вместе с элементом <APIProxy> добавьте элемент <ProxyEndpoint>, чтобы указать название конечной точки прокси-сервера, на которую должен быть направлен звонок.
<LocalTargetConnection> <APIProxy/> <ProxyEndpoint/> </LocalTargetConnection>
| По умолчанию | Н/Д |
| Присутствие | Обязательно |
| Тип | Строка |
Элемент <LocalTargetConnection>/<ProxyEndpoint>
Название конечной точки прокси-сервера, которая должна быть целью звонков. Это конечная точка прокси-сервера в прокси-сервере API, указанном с помощью элемента <APIProxy>.
<LocalTargetConnection> <APIProxy>data-manager</APIProxy> <ProxyEndpoint>default</ProxyEndpoint> </LocalTargetConnection>
| По умолчанию | Н/Д |
| Присутствие | Необязательно |
| Тип | Н/Д |
Элемент <LocalTargetConnection>/<Path>
Путь к целевой конечной точке. Конечная точка должна относиться к прокси-серверу в той же организации и среде, что и прокси-сервер, выполняющий вызов.
Используйте этот код вместо пары <APIProxy>/<ProxyEndpoint>, если вы не знаете или не можете полагаться на имя прокси-сервера. Путь может быть надежной целью.
<LocalTargetConnection> <Path>/data-manager</Path> </LocalTargetConnection>
| По умолчанию | Н/Д |
| Присутствие | Необязательно |
| Тип | Н/Д |
Схемы
Переменные процесса
Переменные потока позволяют динамически изменять поведение правил и потоков во время выполнения на основе заголовков HTTP, контента сообщений или контекста потока. После выполнения правила вызова сервиса доступны следующие стандартные переменные потока: Подробнее о переменных потока…
У выносок сервисов есть собственные запросы и ответы, и вы можете получить доступ к этим данным с помощью переменных. Поскольку в основном сообщении используются префиксы переменных request.* и response.*, для получения данных, относящихся к выноске "Сервис", используйте префиксы myrequest.* и calloutResponse.* (они заданы по умолчанию в конфигурации выноски "Сервис"). В первом примере из таблицы ниже показано, как получить заголовки HTTP в выноске сервиса.
| Переменная | Описание |
|---|---|
|
Ниже приведен пример получения заголовков запроса и ответа для вызова сервиса, аналогичный тому, как вы получаете заголовки для основного запроса и ответа.
где calloutResponse – название переменной для ответа в вызове сервиса, а myRequest – название переменной для запроса. Пример:
возвращает заголовок Content-Length ответа вызова сервиса. |
Область действия: с момента вызова сервиса Заголовок сообщения в запросе или ответе для функции "Вызов сервиса". Например, если целевой адрес прокси API – http://example.com, а целевой адрес вызова сервиса – http://mocktarget.apigee.net, эти переменные будут заголовками для вызова http://mocktarget.apigee.net. |
servicecallout.requesturi |
Область действия: с момента отправки запроса на вызов сервиса URI TargetEndpoint для правила ServiceCallout. URI – это URL TargetEndpoint без протокола и спецификации домена. |
servicecallout.{policy-name}.target.url |
Область действия: с момента отправки запроса на вызов сервиса Целевой URL для выноски с номером телефона. |
|
где |
Область действия: ответа на вызов сервиса и далее. Тело ответа от вызова сервиса. |
servicecallout.{policy-name}.expectedcn |
Область действия: с момента отправки запроса на вызов сервиса Ожидаемое общее название TargetEndpoint, указанное в правиле ServiceCallout. Этот параметр имеет смысл, только если TargetEndpoint относится к конечной точке TLS/SSL. |
servicecallout.{policy-name}.failed |
Область действия: от ответа на вызов сервиса Логическое значение, указывающее, успешно ли применено правило (false) или нет (true). |
Ошибки
В этом разделе описаны коды ошибок и сообщения об ошибках, которые возвращаются, а также переменные ошибок, которые задаются Edge, когда это правило вызывает ошибку. Эта информация важна, если вы разрабатываете правила обработки ошибок. Подробнее о том, что нужно знать об ошибках в правилах и об обработке ошибок…
Ошибки времени выполнения
Эти ошибки могут возникать при выполнении правил.
| Код ошибки | Статус HTTP | Причина | Исправить |
|---|---|---|---|
steps.servicecallout.ExecutionFailed |
500 |
Эта ошибка может возникнуть в следующих случаях:
|
build |
steps.servicecallout.RequestVariableNotMessageType |
500 | Переменная Request, указанная в правиле, не относится к типу Message. Например, если это строка или другой тип, отличный от сообщения, вы увидите эту ошибку. | build |
steps.servicecallout.RequestVariableNotRequestMessageType |
500 | Переменная запроса, указанная в правиле, не относится к типу "Сообщение запроса". Например, если это тип Response, вы увидите эту ошибку. | build |
Ошибки развертывания
Эти ошибки могут возникать при развертывании прокси-сервера, содержащего это правило.
| Название ошибки | Причина | Исправить |
|---|---|---|
URLMissing |
Элемент <URL> внутри <HTTPTargetConnection>
отсутствует или не заполнен. |
build |
ConnectionInfoMissing |
Эта ошибка возникает, если в правиле нет элемента <HTTPTargetConnection> или <LocalTargetConnection>. |
build |
InvalidTimeoutValue |
Эта ошибка возникает, если значение <Timeout> отрицательное или нулевое. |
build |
Переменные ошибок
Эти переменные задаются при возникновении ошибки выполнения. Подробнее о нарушениях правил…
| Переменные | Место | Пример |
|---|---|---|
fault.name="fault_name" |
fault_name – название ошибки, указанное в таблице Ошибки выполнения выше. Название ошибки – это последняя часть кода ошибки. | fault.name = "RequestVariableNotMessageType" |
servicecallout.policy_name.failed |
policy_name – заданное пользователем название правила, которое вызвало ошибку. | servicecallout.SC-GetUserData.failed = true |
Пример ответа об ошибке
{ "fault":{ "detail":{ "errorcode":"steps.servicecallout.RequestVariableNotMessageType" }, "faultstring":"ServiceCallout[ServiceCalloutGetMockResponse]: request variable data_str value is not of type Message" } }
Пример правила обработки ошибок
<faultrule name="VariableOfNonMsgType"></faultrule><FaultRule name="RequestVariableNotMessageType">
<Step>
<Name>AM-RequestVariableNotMessageType</Name>
</Step>
<Condition>(fault.name = "RequestVariableNotMessageType")</Condition>
</FaultRule>Статьи по теме
- Создание и изменение сообщений: назначьте правила для сообщений.
- Извлечение переменных: Extract Variables policy
- Переменные: Variables reference
- Настройка TLS/SSL
- Настройка TLS от Edge до внутреннего сервиса (в облаке и частном облаке)
- Конфигурация целевой конечной точки TLS/SSL" в справочнике по конфигурации прокси-сервера API
- Свойства HTTP-транспорта: справочник по свойствам конечной точки
- Альтернатива вызову сервиса: HTTPClient, написанный на JavaScript. См. объектную модель JavaScript.