Using Policy Expressions in Azure API Management

Policy expressions in Azure API Management provide a powerful way to dynamically configure your policies. They allow you to embed C#-like code snippets within your policy definitions to perform tasks such as accessing request/response properties, manipulating data, and making decisions.

Note: Policy expressions are evaluated during request processing and can significantly impact the performance of your API gateway. Use them judiciously and optimize your expressions for efficiency.

What are Policy Expressions?

Policy expressions are enclosed within the @(expression) syntax. They can be used in various policy elements, including:

Within these expressions, you have access to a rich set of built-in objects and methods representing the context of an API request and response.

Commonly Used Objects and Properties

Here are some of the most frequently used objects within policy expressions:

context Object

The context object provides access to information about the current request and API Management environment. Key properties include:

context.Request Properties

context.Response Properties

Examples of Policy Expressions

1. Setting a Dynamic Header

This example sets a custom response header with the current API Management deployment region.

<policies>
    <inbound>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <set-header name="X-APIM-Region" value="@(context.Deployment.Region)" />
    </outbound>
</policies>

2. Conditionally Routing Requests (using choose)

This policy redirects requests with a specific query parameter to a different backend.

<policies>
    <inbound>
        <base />
        <choose>
            <when condition="@(context.Request.Query.GetValueOrDefault("version", "") == "v2")">
                <send-request mode="new" response-variable-name="v2Response" ignore-error="true">
                    <set-url>https://v2.backend.example.com/api</set-url>
                    <set-method>@(context.Request.Method)</set-method>
                    <set-body template="liquid">@(context.Request.Body.As<string>())</set-body>
                    <set-headers template="liquid">@(context.Request.Headers.Select(h=> $"{h.Key}: {h.Value}"))</set-headers>
                </send-request>
                <choose>
                    <when condition="@(context.Response.StatusCode >= 200 && context.Response.StatusCode < 300)">
                        <set-body>@(context.Variables["v2Response"].Body)</set-body>
                    </when>
                    <otherwise>
                        <return-response>
                            <set-status code="503" reason="Backend Unavailable"/>
                        </return-response>
                    </otherwise>
                </choose>
            </when>
            <otherwise>
                <forward-request />
            </otherwise>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
</policies>

3. Extracting and Manipulating Request Body Data

This example extracts a value from a JSON request body and uses it to set a response header.

<policies>
    <inbound>
        <base />
        <set-variable name="userId" value="@{
            var payload = JObject.Parse(context.Request.Body.AsString());
            return payload["user"]["id"].ToString();
        }" />
        <set-header name="X-User-ID" value="@(context.Variables["userId"])" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
</policies>
Tip: For complex JSON manipulation, you can leverage the JObject.Parse() and related methods from the Newtonsoft.Json library within your policy expressions.

Policy Expression Syntax and Language

Policy expressions are essentially C# snippets. You can use:

The available .NET framework assemblies are limited to those commonly used in the Azure Functions runtime. You can access certain common namespaces without explicit `using` statements.

Debugging Policy Expressions

Debugging policy expressions can be challenging. The most effective method is to:

  1. Use the API Management diagnostic logs. These logs capture request and response details, including the values of variables and headers manipulated by policies.
  2. Test policies incrementally. Add one policy at a time and verify its behavior before adding the next.
  3. Use the log-to-eventhub policy to send custom messages to your event hub for more detailed inspection.
Important: Be mindful of the order of policies in your policy definition. Policies are executed sequentially, and the output of one policy can be the input for another.

Performance Considerations

Complex or inefficient policy expressions can lead to increased latency. Always consider the performance implications: