Apigee Edge enables you to 'program' API behavior without writing any code, by using 'policies'. A policy is like a module that implements a specific, limited management function. Policies are designed to let you add common types of management capabilities to an API easily and reliably. Policies provide features like security, rate-limiting, transformation, and mediation capabilities, saving you from having to code and maintain this functionality on your own. 

You're not limited to the set of policy types provided by Apigee Edge. You can also write custom scripts and code (such as JavaScript and Node.js applications), that extend API proxy functionality and enable you to innovate on top of the basic management capabilities supported by Apigee Policies.

Policy types

Technically, a policy is an XML-formatted configuration file. Each policy type's structure (for example, the required and optional configuration elements) is defined by an XML schema. If you are proficient with XML tools, it is worthwhile to familiarize yourself with the policy schemas in the API Platform samples on Github.

Edge Policy types are grouped into the following functional categories:

Traffic management

Policies in the traffic management category enable you to control the flow of request and response messages through an API proxy. These policies support both operational- and business-level control. They give you control over raw throughput, and can also control traffic on a per-app basis. Traffic management policy types enable you to enforce quotas, and they also help you to mitigate denial of service attacks.

Mediation

Policies in the mediation category enable you to actively manipulate messages as they flow through API proxies. They enable you to transform message formats, from XML to JSON (and vice-versa), or to transform one XML format to another XML format.  They also enable you to parse messages, to generate new messages and to change values on outbound messages. Mediation policies also interact with basic services exposed by API Services, enabling you to retrieve data about apps, developers, security tokens, and API products at runtime. 

Security

Policies in the security category support authentication, authorization, as well as content-based security.

Extension 

Policies in the extension category enable you to tap into the extensibility of API Services to implement custom behavior in the programming language of you choice.

Each Policy type is documented in detail in the Policy reference overview. This topic demonstrates general interaction, showing you how to create Policies, and how to attach them to Flows in an API proxy configuration.

Configuring and attaching policies 

Adding policy-based capabilities to an API proxy is a two-step process:

  1. Configure an instance of a policy type.
  2. Attach the policy instance to a Flow.

The diagram below shows the relationship between policies and Flows. As you can see, a policy is attached to a Flow as a processing "Step". To configure the desired behavior for your API, you need to understand a little bit about Flows. (This topic was covered earlier in Flows.)

One type of policy that is commonly used is SpikeArrest. SpikeArrest prevents sudden increases in message traffic that might swamp your backend services.

To attach a policy to a Flow:

  1. Select an API proxy and navigate to the Develop view
  2. In the API Proxy Editor, select the New Policy drop-down menu.

    A categorized list of the available policy types displays.

  3. Select the policy type that you want to add to the API proxy.

    For example, if you want to add a SpikeArrest policy, select the Traffic Management category in the policy dropdown menu.

  4. Modify the selections in the New Policy dialog to configure and attach the policy.

    If you accept the default selections, as shown below, the policy will be enforced on request messages submitted by client apps to the ProxyEndpoint PreFlow.

    The New Policy form provides the following options:

    • Policy Name: A unique name for this policy. The UI will generate a default name, but it is advisable to create a descriptive name for the policy. This will ensure that other developers in your organization have an easy time understanding what the policy is intended to do. The UI changes spaces to dashes, changes consecutive dashes to a single dash, and removes characters that are not alphanumeric, such as dashes, underscores, and percent signs. 

    • Attach Policy: By selecting this checkbox, you will cause the policy to be attached to the specified Flow when the policy is created, that is, when you select Add. Deselect this box if you do not want to attach the policy yet.

    • Flow: Displays a drop-down list of Flows in this API proxy. Select the Flow to which the policy should be attached. Four default Flows are available. (If you added conditional Flows to your API proxy, they will display here as options.)  To learn more about Flows, see Flows.

    • Segment: Each Flow has a request and response 'segment'. Select the radio button for the segment to which you want to attach the policy. It's important to attach a policy to the right Flow and segment.

      Of course, if you deselect the Attach Policy checkbox, the policy won't be attached to a Flow. The policy will be created, but it won't be enforced. You might do this if you simply want to configure a policy and later decide its attach points. You can attach the policy later by selecting it in the Navigator view and then clicking Attach Policy.)

  5. When you finish configuring the policy, select Add

    The policy is attached to the Flow that you selected.

  6. After you select Add, you’ll see the policy displayed in the Designer view for the PreFlow of the default ProxyEndpoint. The Code view, which displays the XML for the newly attached policy, displays below the Designer view of the Flow. Note that the UI has generated an instance of the policy that contains a set of reasonable default values.

     

To detach a policy from a Flow: Select the Flow. Mouse over the icon for the policy in the Designer view of the Flow. Click the X in the circle that appears in the icon.

To delete a policy instance: Mouse over the entry for the policy in the Navigator view. Click the X in the circle that appears to the right of the entry.

Configuring policies

When the UI generates a policy instance, it applies reasonable default values for common settings. You may need to modify these settings to meet your requirements.

For example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SpikeArrest async="false" continueOnError="false" enabled="true" name="spikearrest-1">
  <DisplayName>SpikeArrest-1</DisplayName>
  <FaultRules/>
  <Properties/>
  <Identifier ref="request.header.some-header-name"/>
  <MessageWeight ref="request.header.weight"/>
  <Rate>30ps</Rate>
</SpikeArrest>

You can configure a policy by directly editing its XML configuration in the Code view. For example, the peak message rate for the Spike Arrest policy is initially set to 30 messages per second. You can change the peak rate by changing the <Rate> element value in the XML for the policy. For further details about configuring policies, see the Policy Reference.

You can also cut-and-paste policies into the Code view. This is a great way to re-use policies from the samples available on GitHub.

When you make changes to a policy definition in the Code view, the changes are reflected in the Property Inspector. The reverse is also true — make changes in the Property Inspector and they appear in the XML in the Code view.

Some policies expose XML elements that can have multiple subelements. For example, the AssignMessage policy (which is used in the request or response path to generate a new message or to modify an existing message) exposes various elements in which multiple query parameters can be specified. In these cases, the Property Inspector displays an (+) icon. Click the icon to add entry fields for additional subelements.

For documentation specific to the Quota policy used in this topic, see Quota policy.

Working with Policies on your machine

You can create and edit Policies locally, using your favorite text or XML-aware editor or IDE. This topic uses the Quota policy type as an example of how to create, configure, attach, deploy, and test policies.

Most API proxies enforce a quota. Quotas provide control over how often a client app is permitted to invoke an API over a given time interval. In the example below, a Quota policy is configured to limit apps to 1 request per minute. (While this may not be realistic, it does provide a simple way to see the effects of a policy.)

In an API proxy configuration, Policy files are stored as XML files under /apiproxy/policies directory.

For example, a policy of type Quota called "QuotaPolicy" could be created as a file called QuotaPolicy.xml with the following content:

<Quota enabled="true" continueOnError="false"
async="false" name="QuotaPolicy">
    <Allow count="1"/>
    <Interval>1</Interval>
    <TimeUnit>minute</TimeUnit>
</Quota>

You can create a text file by hand, or you can generate the policy from an XML schema. All policies have some settings that are specific to the policy type, and some settings that are generic across all policies. For reference, policy schemas are provided in the API Platform samples on GitHub.

When you attach policies in the management UI, the API proxy builder generates the policy instance from the XML schema for the policy type you selected. Therefore, you may see elements in the policy configuration that, for clarity, are not always included in documentation. 

All policies define the following attributes:

  • enabled: Indicates whether the policy is turned "on" or "off". Policies can be enabled/disabled at runtime by changing this setting. A policy that has enabled set to false is not enforced.
  • continueOnError: Defines whether the pipeline should continue processing the message if the policy fails. When enforcing quota policies, errors likely indicate that the quota has been exceeded, and, therefore, this attribute should be set to false.
  • async: In a policy, enabling async=true tells API Services to run the policy inside a different thread pool, isolated from the regular pool that is servicing the request/response Flow. This is an internal optimization that will rarely be of use to API developers.
  • name: The name that you give to this policy. This name is unique to this policy instance, and it is used to attach the policy to the flow as a processing step.

Except for name, you rarely need to modify the default settings for these policy attributes. For this reason, and for clarity, they are often excluded from the policy samples in the documentation.

In the example above, the elements Allow, Interval, and TimeUnit are specific to the Quota policy. These elements provide settings that API Services enforces on behalf of an API. Other policy types define their own settings, which you can learn about in the Policy Reference.

Attaching a policy to a ProxyEndpoint or TargetEndpoint Flow

Policies are not executed until they are attached to a Flow. You can create a Policy attachment by naming a Policy in a Step configuration.

The choice of attachment point is critical to the behavior of your API proxy. For example, if you attach the Quota policy to a response Flow, then the Quota would be enforced after the request message was sent to the backend service. That would defeat the purpose of applying a Quota policy! Therefore, you need to attach the Quota policy as a processing Step on the request Flow.

The format of a policy attachment is:

<Step>
    <Name>{policy_name}</Name>
</Step>

For example:

<Step>
    <Name>QuotaPolicy</Name>
</Step>

The {policy_name} variable must be the same as the name attribute in the policy (stored under /policies) that you want to attach. The names must match exactly, as name matching is case-sensitive.

A policy is attached to a Flow by adding the Step configuration to the appropriate request or response Flow element in a ProxyEndpoint or TargetEndpoint configuration.

You can attach a policy to a request or response Flow. Request and response Flows are further subdivided in to PreFlow and PostFlow.

The following example demonstrates the minimal ProxyEndpoint configuration, with no policy attachments. It simply defines the (inbound) HTTPProxyConnection and a RouteRule.

<ProxyEndpoint name="default">
    <HTTPProxyConnection>
        <BasePath>/weather</BasePath>
        <VirtualHost>default</VirtualHost>
    </HTTPProxyConnection>
  <RouteRule name="default">
     <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

You must modify this configuration so that the ProxyEndpoint enforces a Quota policy (as a processing Step) before the API proxy performs any other processing. If a developer has exceeded a Quota, you don't want to waste any computational resources on additional requests.

To enforce this configuration, you attach a processing Step to the request PreFlow as follows:

<ProxyEndpoint name="default">
  <PreFlow>
    <Request>
      <Step><Name>QuotaPolicy</Name></Step>
    </Request>
  </PreFlow>
  <HTTPProxyConnection> 
    <BasePath>/weather</BasePath> 
    <VirtualHost>default</VirtualHost> 
  </HTTPProxyConnection> 
  <RouteRule name="default"> 
    <TargetEndpoint>default</TargetEndpoint> 
  </RouteRule> 
</ProxyEndpoint>

Sometimes, you might want a policy to execute after some other initial processing on the ProxyEndpoint. For example, you want to check Quota in the PreFlow, then perform another set of processing after Quota is checked, such as converting the request from JSON to XML. To do so, attach a policy to the PostFlow request path. The following is a sample request PostFlow attachment. This policy would execute on the request message after all of the policies in the PreFlow (and any conditional flows) execute.

<PostFlow>
  <Request>
    <Step><Name>JSONtoXMLPolicy</Name></Step>
  </Request>
</PostFlow>

The following is a sample response PostFlow attachment. This policy would execute on the response message. (The ProxyEndpoint response PostFlow is the final processing phase before the response is returned to the requesting client app.)

<PostFlow>
  <Response>
    <Step><Name>XMLtoJSONPolicy</Name></Step>
  </Response>
</PostFlow>

You can also define conditional Flows that execute between the PreFlow and PostFlow phases. This is covered in the next topic, Flow variables and conditions.

Deploying policy changes

For policy changes to take effect, you must deploy the API proxy revision to an environment. After you attach a policy or make changes to an existing policy, use the management UI or the management API to deploy the changes.

Verifying policy enforcement

To verify that a policy is enforced properly, the API must be invoked by an HTTP client. To verify this Quota configuration, submit multiple requests to the API, exceeding the quota limit that you set in the quota policy. (The URI path, configured as the base path setting in the ProxyEndpoint, in the request below is /weather).

http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

After you submit more than 1 request within a minute, you should see the following error message:

{"fault":{"faultstring":"policies.ratelimit.QuotaViolation","detail":{"errorcode":"policies.ratelimit.QuotaViolation"}}}

This indicates that the Quota policy is being enforced by API Services.

Policy-based fault handling

Note the format of the error message above. It contains a faultstring property and an errorcode property. In many cases, you need to implement some behavior to handle these errors. For example, you may wish to issue a customized message to a developer whose app has exceeded the Quota.

To do so, you use the FaultRule element on the Step. A FaultRule element can be attached to any policy. The behavior of a the FaultRule is defined by the Policy that you attach to the FaultRule.

For example,

<Step>
 <FaultRules>
  <FaultRule>
    <Name>QuotaLimitAlertPolicy</Name>
    <Condition>(fault.name = ratelimit.QuotaLimitCheck.exceed.count)</Condition>
  <FaultRule>
 <FaultRules>
 <Name>QuotaPolicy</Name>
 </Step>

In the example above the Policy named QuotaLimitAlertPolicy would typically be an AssignMessage Policy that generates a custom response message.

For more on fault handling, see Fault handling.

Best practices: Common policy sets

To meet basic management requirements, API proxies usually enforce the following policies:

Basic API key validation

ProxyEndpoint Request Flow:
  1. SpikeArrest
  2. XMLThreatProtection or JSONThreatProtection
  3. API key validation
  4. Quota
  5. ResponseCache
ProxyEndpoint Response Flow:
  1. ResponseCache

Basic transformation: JSON to XML

Request Flow:
  1. SpikeArrest
  2. JSONThreatProtection
  3. API key validation
  4. Quota
  5. JSONToXML
Response Flow:
  1. XMLToJSON
  2. ResponseCache

Working samples of policy configurations are available in the Using the samples on GitHub.

 

Help or comments?

  • Something's not working: See Apigee Support
  • Something's wrong with the docs: Click Send Feedback in the lower right.
    (Incorrect? Unclear? Broken link? Typo?)