Send Docs Feedback

Service Callout policy

What

The Service Callout policy lets you call to an external service from your API proxy flow. A typical use case involves a service callout from a response flow to a third-party API (the external service). The response from the third-party API is parsed and inserted in your API's response message, enriching and "mashing up" the data for app end users.

Or, you can make a request using the Service Callout policy in the request flow, then pass the information in the response to the TargetEndpoint of the API proxy.

The policy supports requests over HTTP and HTTPS.

Where

This policy can be attached in the following locations.

ProxyEndpoint TargetEndpoint
    PreFlow Flow PostFlow PreFlow Flow PostFlow    
Request    
    Response
    PostFlow Flow PreFlow PostFlow Flow PreFlow    

Samples

<ServiceCallout name="GeoCodeClient">
    <Request clearPayload="false" variable="GeocodingRequest"/>
    <Response>GeocodingResponse</Response>
    <Timeout>30000</Timeout>
    <HTTPTargetConnection>
      <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
    </HTTPTargetConnection>
</ServiceCallout>

This policy submits a request to the Google Geocoding API at http://maps.googleapis.com/maps/api/geocode/json. The content of the request message is extracted from a variable called GeocodingRequest (which could be populated, for example, by an AssignMessage policy). The response message is assigned to the variable called GeocodingResponse, where it is a available to be parsed, for example, by an Extract Variables policy or by custom code written in JavaScript or Java. The policy waits 30 seconds for the response from the Google Geocoding API before timing out.

For a complete sample API proxy that uses this example Service Callout, along with the Assign Message and Extract Variables policies, see Using policy composition

<HTTPTargetConnection>
    <URL>http://example.com/{request.myResourcePath}</URL>
</HTTPTargetConnection>

This example uses a variable in the URL to dynamically populate the URL of the target. The protocol portion of the URL, http://, cannot be specified by a variable. Also, you must use separate variables for the domain portion of the URL and for the rest of the URL.

<ServiceCallout name='ServiceCallout-GetBaasToken'>
    <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>

Instead of using a policy such as Assign Message to create the request object, you can define it directly in the Service Callout policy. In this example, the Service Callout policy sets the values of three query parameters passed to the external service. You can create an entire request message in the Service Callout policy that specifies a payload, encoding type such as application/xml, headers, form parameters, etc.


About the Service Callout policy

There are many scenarios where you can use a Service Callout policy in your API proxy. For example, you can configure an API proxy to make calls to an external service to deliver geolocation data, customer reviews, items from a partner’s retail catalog, and so on.

The Service Callout is typically used with two other policies: Assign Message and Extract Variables.

  • Request: Assign Message populates the request message sent to the remote service.
  • Response: Extract Variables parses the response and extracts specific content.

The typical Service Callout policy composition involves:

  1. Assign Message policy: Creates a request message, populates HTTP headers, query parameters, sets the HTTP verb, etc.
  2. Service Callout policy: References a message created by the Assign Message policy, defines a target URL for the external call, and defines a name for the response object that the target service returns.
  3. Extract Variables policy: Typically defines a JSONPath or XPath expression that parses the message generated by the Service Callout. The policy then sets variables containing the values parsed from the Service Callout response. 

One consideration with the Service Callout policy is that you should not use it to make requests to other API proxies in the same organization, including recursive callouts back into the same API proxy. 

See Using policy composition for a complete sample API proxy that uses the Service Callout policy along with the Assign Message and Extract Variables policies. The source code for that sample is available at API Platform samples on Github.

An alternative approach to Service Callout is an HTTPClient written in JavaScript using the JavaScript object model. For a working sample and code walkthrough, see Implementing HTTP clients in JavaScript.

Element reference

Following are elements and attributes you can configure on this policy:

<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>60000</Timeout>
    <HTTPTargetConnection>
        <URL>http://example.com</URL>
        <SSLInfo/>
        <Properties>
    </HTTPTargetConnection>
</ServiceCallout>

<ServiceCallout> attributes

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">

The following attributes are common to all policy parent elements.

Attribute Description Default Presence
name

The internal name of the policy. Characters you can use in the name are restricted to: A-Z0-9._\-$ %. However, the Edge management UI enforces additional restrictions, such as automatically removing characters that are not alphanumeric.

Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

N/A Required
continueOnError

Set to false to return an error when a policy fails. This is expected behavior for most policies.

Set to true to have flow execution continue even after a policy fails.

false Optional
enabled

Set to true to enforce the policy.

Set to false to "turn off" the policy. The policy will not be enforced even if it remains attached to a flow.

true Optional
async

Note: This attribute does not make the policy execute asynchronously.

When set to true, policy execution is offloaded to a different thread, leaving the main thread free to handle additional requests. When the offline processing is complete, the main thread comes back and finishes handling the message flow. In some cases, setting async to true improves API proxy performance. However, overusing async can hurt performance with too much thread switching.

To use asynchronous behavior in API proxies, see JavaScript callouts.

false Optional

<DisplayName> element

Use in addition to the name attribute to label the policy in the management UI proxy editor with a different, natural-language name.

<DisplayName>Policy Display Name</DisplayName>
Default:

N/A

If you omit this element, the the value of the policy's name attribute is used.

Presence: Optional
Type: String

 

<Request> element

Specifies the variable containing the request message that gets sent from the API proxy to the external service. The variable can be created by a previous proxy in the flow, or you can create it inline in the Service Callout policy.

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

The syntax for the <Remove>, <Copy>, <Add>, and <Set> tags is the same as for the Assign Message policy.

The policy returns an error if the request message cannot be resolved or is of an invalid request message type.

In the simplest example, you pass a variable containing the request message that was populated earlier in the flow of the API proxy:

<Request clearPayload="true" variable="myRequest"/>

Or you populate the request message in the Service Callout policy itself:

<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>
Default N/A
Presence

Optional. If omitted, the policy uses by default the following setting:

<Request clearPayload="false" variable="request"/>

Meaning, that the current request object is used as the request message sent to the external service. 

Type N/A

Attributes

Attribute Description Default Presence
variable

Name of the variable that will contain the request message.

NA Optional
clearPayload

If true, the variable containing the request message is cleared after the request is sent to the HTTP target to free up the memory used by the request message.

Use the clearPayload option only if the request message is not required after the Service Callout is executed.

false Optional

<Request>/<IgnoreUnresolvedVariables> element

When set to true, the policy ignores any unresolved variable error in the request.

<Request clearPayload="true" variable="myRequest">
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request> 
Default false
Presence Optional
Type Boolean

<Response> element

When the API proxy expects a response from the Service Callout, specifies the name of the variable that will contain the response message received from the external service.

The output generated by the policy is assigned to the variable only when the entire response is read successfully by the policy. If the response message fails for any reason, the policy returns an error.

If this element is not specified, the API proxy does not wait for response to be completely read and executes the message flow steps. Also, the response from the target is not available so there is no way to access the response.

 <Response>calloutResponse</Response> 
Default NA
Presence Optional
Type String

<Timeout> element

The time in milliseconds that the Service Callout policy will wait for a response from the target before exiting.

<Timeout>60000</Timeout>
Default 120000 milliseconds (120 seconds), the default HTTP timeout setting for Apigee Edge
Presence Optional
Type Integer

<HTTPTargetConnection> element

Provides transport details such as URL, SSL, and HTTP properties. See the TargetEndpoint configuration reference.

You can use flow variables to construct the URL in an <HttpTargetConnection> element. 

<HTTPTargetConnection>
    <URL>http://example.com</URL>
    <SSLInfo/>
    <Properties/>
</HTTPTargetConnection>
Default N/A
Presence Required
Type N/A

<HTTPTargetConnection>/<URL> element

The URL to the service being called:

<HTTPTargetConnection>
    <URL>http://example.com</URL>
</HTTPTargetConnection>

You can supply part of the URL dynamically with a variable. However, the protocol portion of the URL, http:// below, cannot be specified by a variable. In the next example, you use a variable to specify the value of a query parameter:

<URL>http://example.com/forecastrss?w=${request.header.woeid}</URL>

Or, set a portion of the URL path with a variable:

<URL>http://example.com/{request.resourePath}?w=${request.header.woeid}</URL>

If you want to use a variable to specify the domain and port of the URL, then use one variable for the domain and port only, and a second variable for any other part of the URL:

<URL>http://{request.dom_port}/{request.resourePath}</URL>
Default N/A
Presence Required
Type String

<HTTPTargetConnection>/<SSLInfo> element

The SSL configuration to the backend service. For help on SSL configuration, see Configuring SSL from Edge to the backend service (cloud and Private Cloud) and "Advanced TargetEndpoint Configuration" in API proxy configuration reference.

<HTTPTargetConnection>
    <URL>http://example.com</URL>
    <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>myKeystore</KeyStore>
        <KeyAlias>myKey</KeyAlias>
        <TrustStore>myTruststore</TrustStore>
        <Ciphers/>
        <Protocols/>
    </SSLInfo>
</HTTPTargetConnection>
Default N/A
Presence Optional
Type N/A

<HTTPTargetConnection>/<Properties> element

HTTP transport properties to the backend service. For more information, see Endpoint properties reference.

<HTTPTargetConnection>
    <URL>http://example.com</URL>
    <Properties>
        <Property name="allow.http10">true</Property>
        <Property name="request.streaming.enabled">true</Property>
        <Property name="request.retain.headers">
          User-Agent,Referer,Accept-Language
        </Property>
    </Properties>
</HTTPTargetConnection>
Default N/A
Presence Optional
Type N/A

Schemas

See our Github repository samples for the most recent schemas.

Flow variables

Flow variables enable dynamic behavior of policies and Flows at runtime, based on HTTP headers, message content, or Flow context. The following predefined Flow variables are available after a Service Callout policy executes. For more information about Flow variables, see Variables reference.

Variable Description
servicecallout.requesturi

Scope: Proxy request
Type: String
Permission: Read/Write

The TargetEndpoint URI for a ServiceCallout policy. The URI is the TargetEndpoint URL without the protocol and domain specification.

servicecallout.{policy-name}.expectedcn

Scope: Proxy request
Type: String
Permission: Read/Write

The expected Common Name of the TargetEndpoint as referred to in a ServiceCallout policy. This is meaningful only when the TargetEndpoint refers to an SSL endpoint.

servicecallout.{policy-name}.target.url

Scope: Proxy request
Type: String
Permission: Read/Write

The TargetEndpoint URL for a particular ServiceCallout policy. 

servicecallout.{policy-name}.failed

Scope: Proxy request
Type: Boolean
Permission: Read/Write

Boolean indicating if the policy succeeded, false, or failed, true.

ServiceCallout.response

Scope: Proxy request
Type: String
Permission: Read/Write

The response from the service callout.

Error codes

The default format for error codes returned by Policies is:

{
  "code" : " {ErrorCode} ",
  "message" : " {Error message} ",
  "contexts" : [ ]
}

By default, Edge treats HTTP codes 4XX or 5XX as errors, and it treats HTTP codes 1XX, 2XX, 3XX as success. However, you can use the <HTTPTargetConnection> tag to configure your own set of HTTP codes that generate errors. See Fault handling for more.  

The Service Callout policy defines the following error codes. For guidance on handling errors, see Fault handling.

Error Code Message
ConnectionInfoMissing Connfaection information is missing in Step {0}
ExecutionFailed Execution of ServiceCallout {0} failed. Reason: {1}
RequestVariableIsNull ServiceCallout[{0}]: request variable {1} value is null
RequestVariableNotMessageType ServiceCallout[{0}]: request variable {1} value is not of type Message
RequestVariableNotRequestMessageType ServiceCallout[{0}]: request variable {1} value is not of type Request Message
ErrorResponseCode ResponseCode {0} is treated as error
InvalidTimeoutValue Invalid Timeout value {0}
URLMissing JSONToXML[{0}]: Output variable is not available.

Related topics

For working samples of API proxies, see the Samples reference.

 

Help or comments?