Transforming and protecting APIs in Azure API Management (APIM) is a critical aspect of ensuring that your APIs are secure, scalable, and optimized for consumption. Azure APIM provides a rich set of policies to transform requests and responses, as well as protect APIs from unauthorized access, abuse, and attacks.
In this explanation, we’ll cover:
We’ll use a live example to demonstrate these concepts.
Transforming APIs involves modifying the request or response to meet specific requirements. Common use cases include:
Let’s assume we have an API that returns user details in XML format, but we want to transform the response to JSON for better compatibility with modern clients.
GET /users
) or use an existing one.Azure APIM uses XML-based policies to transform requests and responses. Here’s how you can transform the response from XML to JSON:
<policies> <inbound> <base /> <!-- Forward the request to the backend --> </inbound> <backend> <base /> </backend> <outbound> <base /> <!-- Transform the response from XML to JSON --> <xml-to-json kind="direct" apply="always" consider-accept-header="false" /> <!-- Add a custom header --> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> </outbound> <on-error> <base /> </on-error> </policies>
GET
request to /users
.<users> <user> <id>1</id> <name>John Doe</name> </user> <user> <id>2</id> <name>Jane Smith</name> </user> </users>
{ "users": { "user": [ { "id": 1, "name": "John Doe" }, { "id": 2, "name": "Jane Smith" } ] } }
Protecting APIs involves securing them against unauthorized access, abuse, and attacks. Azure APIM provides several policies for this purpose, including:
Add a rate-limiting policy to restrict the number of requests to 10 requests per minute per subscription.
<policies> <inbound> <base /> <!-- Validate API key --> <validate-subscription exists-action="error" /> <!-- Rate limiting: 10 requests per minute --> <rate-limit calls="10" renewal-period="60" /> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
GET
request to /users
without an API key. You’ll receive a 401 Unauthorized
error.429 Too Many Requests
error.You can restrict access to your API based on the client’s IP address. For example, allow only requests from specific IP ranges.
<policies> <inbound> <base /> <!-- Allow only requests from specific IP ranges --> <ip-filter action="allow"> <address-range from="192.168.1.0" to="192.168.1.255" /> </ip-filter> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
192.168.1.0/24
will be blocked with a 403 Forbidden
response.Let’s assume we have a backend weather API that returns data in XML format. We want to:
GET /weather
.city
.<policies> <inbound> <base /> <!-- Validate API key --> <validate-subscription exists-action="error" /> <!-- Rate limiting: 5 requests per minute --> <rate-limit calls="5" renewal-period="60" /> </inbound> <backend> <base /> </backend> <outbound> <base /> <!-- Transform response from XML to JSON --> <xml-to-json kind="direct" apply="always" consider-accept-header="false" /> <!-- Add a custom header --> <set-header name="Content-Type" exists-action="override"> <value>application/json</value> </set-header> </outbound> <on-error> <base /> </on-error> </policies>
GET /weather?city=London
with a valid API key.<weather> <city>London</city> <temperature>15</temperature> <unit>Celsius</unit> </weather>
{ "weather": { "city": "London", "temperature": 15, "unit": "Celsius" } }
429 Too Many Requests
error.