Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 79

Transforming Requests and Responses with Policies

Recommended resources

Hello! Welcome back to our module on Azure API Management.

In our last lesson, you did some excellent work securing your API. You learned how to apply policies to control who can call your API (using JWT validation) and how often (using rate limiting). These are crucial inbound controls that protect your backend services.

Today, we'll build on that by exploring policies that control what data flows through the gateway. This lesson is all about transformation. You will learn to apply policies to transform a request or response, such as modifying headers, rewriting URLs, and even changing the structure of the message body. This capability is at the heart of what makes APIM such a powerful tool for decoupling clients from backend services and is a key topic for the AZ-204 exam.

1. The Concept of API Transformation

Before we dive into specific policies, let's solidify the "why." Why would you want to change a request or response as it passes through the gateway?

  • Compatibility: You might have a modern client application that expects JSON, but it needs to communicate with a legacy backend that only produces XML. APIM can handle the translation.
  • Decoupling: Your backend API might have a URL structure like /api/v1/users?userId=123. You can expose a cleaner, more user-friendly URL like /users/123 to your clients and have APIM rewrite it internally. If the backend URL changes later, you only update the APIM policy, and your clients are unaffected.
  • Security: A backend service might return headers that reveal information about the server technology (like X-AspNet-Version). It's a security best practice to remove these before the response reaches the client.
  • Enrichment: You can add information to the request before it reaches the backend. For example, you could add a header with the name of the product the user is subscribed to, allowing your backend to tailor its logic.

All these transformations are made possible by policy expressions. As you've seen, policies are XML snippets, but they can contain C# expressions using the @(...) syntax. These expressions give you access to the request and response context, allowing for dynamic and powerful manipulations.

To start, let's watch a short video that provides a high-level overview of policies and where they fit in the request pipeline.

AZ-204 - Connect and Consume services - Azure API Management

This clip from a video by Alan Rodrigues gives a concise overview of what policies are and the different stages where they can be applied: inbound, backend, outbound, and on-error. This will be a good refresher.

Watch from 01:05:31 to 01:08:30. Focus on understanding the different processing sections (inbound, outbound) as we will be applying transformation policies in both.


2. Inbound Transformations: Modifying the Incoming Request

Inbound transformations modify the request before it is forwarded to your backend API. This is useful for standardizing requests, enriching them with data, or routing them based on their content.

Example 1: Rewriting the Request URL

A very common transformation is to change the URL. Imagine your client calls /courses?id=az204 but your backend expects /api/course/az204. The rewrite-uri policy can handle this translation seamlessly.

The following video demonstrates this exact scenario.

AZ-204 - Connect and Consume services - Azure API Management

This segment clearly demonstrates how to use the rewrite-uri policy to transform a query parameter into a path segment, a very practical use case.

Watch from 01:10:20 to 01:13:48. Notice how the policy uses a C# expression to read the query parameter from the context.Request object and then constructs a new URL template.

The core of this policy looks like this:

<rewrite-uri template="/api/course/@(context.Request.Url.Query.GetValueOrDefault("courseid"))" />

Here, @(...) executes a C# expression to extract the courseid query parameter and embed it into the new path.

Example 2: Adding Context with Request Headers

You can also use policies to add headers to the request before it reaches the backend. This is a great way to pass along context that your backend might need.

Let's look at how to add headers that contain the product name and user ID associated with the API call. Given your C# background, you'll recognize the syntax for accessing properties on the context object.

API Management - Hands-on Lab Script - part 4

This lab guide contains excellent, practical examples of different policies. We'll use a specific section to see how to add headers with dynamic values.

Read the section titled 'Amend what’s passed to the backend'. Focus on the XML snippet that uses the set-header policy with C# expressions like @(context.Product.Name) and @(context.User.Id). This shows how to enrich the request with data available only at the gateway.

Azure API Management: Backend Request Transformation Trace
This trace from the APIM test console shows the result of inbound policies. Notice how the `x-product-name` and `x-request-context-data` headers have been added to the request being forwarded to the backend, just as the policy defined.

3. Outbound Transformations: Modifying the Outgoing Response

Outbound transformations modify the response from your backend before it is sent back to the client. This is where you can clean up data, change its format, or add custom headers.

Example 1: Setting and Removing Response Headers

A simple and common task is to manage response headers. You might add a custom header for tracking or remove a default header for security.

Transform and protect your API in Azure API Management

This Microsoft Learn article provides a very clear, step-by-step guide for adding a custom header to a response using the form-based policy editor in the Azure portal.

Read the sections 'Transform an API to add a custom response header' and 'Test the custom response header'. Follow the steps to understand how to use the set-header policy in the outbound section.

To remove a header, you use the same set-header policy but with a different action. This is useful for removing headers like X-Powered-By that could leak information about your backend technology. The lab script you looked at earlier shows a perfect example of this.

<outbound>
    <base />
    <!-- Add a custom header -->
    <set-header name="X-Custom-Header" exists-action="override">
        <value>My custom value</value>
    </set-header>
    <!-- Remove a potentially revealing header -->
    <set-header name="x-aspnet-version" exists-action="delete" />
</outbound>

Example 2: Transforming the Response Body

Modifying the body of the response is an even more powerful capability.

Simple String Replacement
You can perform a simple find-and-replace on the response body. For instance, if your backend returns a term you want to change for public consumption, the find-and-replace policy is ideal.

Azure API Management Policy for Response Transformation
This image shows the XML policy editor in the Azure portal. It demonstrates an outbound `find-and-replace` policy that will substitute the string "blue" with "yellow" in the response body.

Conditional Transformations with C#
You can also perform more complex, conditional transformations. For example, you could strip out certain properties from a JSON object for users on a "Starter" plan but return the full object for "Unlimited" plan users.

Since you're proficient in C#, the policy expression for this will look familiar. It involves parsing the response body into a JSON object and then manipulating it directly.

API Management - Hands-on Lab Script - part 4

Let's return to the hands-on lab script to see an advanced example of a conditional body transformation.

Read the section titled 'Transformation - conditional'. Pay close attention to the <set-body> policy. Notice how it uses a C# code block @{ ... } to parse the JSON body and remove properties if the product name is 'Starter'. This is a prime example of APIM's flexibility.


Hands-On Practice

Now it's your turn to apply a transformation. Let's try a simple outbound transformation.

  1. Navigate to your APIM instance and select the API you have been working with.

  2. Select an operation (e.g., GET /WeatherForecast).

  3. Go to the Design tab and in the Outbound processing section, click the </> icon to open the policy editor.

  4. Inside the <outbound> section, add a policy to set a new header and remove an existing one. If your backend is an ASP.NET Core app, it likely includes an X-Powered-By header you can practice removing.

    <outbound>
        <base />
        <set-header name="X-Source" exists-action="override">
            <value>Processed-by-APIM</value>
        </set-header>
        <set-header name="X-Powered-By" exists-action="delete" />
    </outbound>
    
  5. Save the policy.

  6. Go to the Test tab, send a request to the operation, and inspect the response headers. You should see your new X-Source header and confirm that the X-Powered-By header is gone.


Conclusion

You have now seen how API Management can act as a powerful transformation layer between your clients and backends. This decoupling is a fundamental principle of modern API architecture and a key skill for an Azure developer.

Key Takeaways:

  • Policies can transform both requests (inbound) and responses (outbound).
  • The rewrite-uri policy is used to change the request path and query string, decoupling client-facing URLs from backend implementations.
  • The set-header policy can add, modify, or delete headers, which is useful for enriching context or enhancing security.
  • The find-and-replace and set-body policies allow for modification of the message body, from simple string substitution to complex, conditional logic using C# expressions.
  • The context variable is the key to dynamic transformations, providing access to all information about the request, response, product, user, and more.

Next Steps

Your API is now proxied, secured, and capable of transformation. However, your backend App Service is likely still accessible via its public URL (*.azurewebsites.net). In a real-world scenario, you would want to lock this down so that it only accepts traffic from your APIM instance. In our next lesson, we will cover exactly that: securing your backend API.