Azure API Management Versioning & Revisions
Managing API Evolution and Changes
Introduction
As APIs evolve, you need to manage changes without breaking existing consumers. Azure API Management provides built-in capabilities for API versioning and revisions that allow you to introduce changes safely and manage the API lifecycle effectively.
This comprehensive guide covers:
- Versioning — Supporting multiple API versions
- Version schemes — Path, header, and query parameter
- Revisions — Making non-breaking changes
- Version sets — Grouping related versions
- Best practices — API evolution strategies
API Versioning
Why Version?
┌─────────────────────────────────────────────────────────────────────┐
│ API VERSIONING NEED │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Timeline: │
│ │
│ Jan ──── Feb ──── Mar ──── Apr ──── May ──── Jun ──── Jul │
│ │ │ │ │ │ │
│ │ v1.0 │ v1.1 │ v2.0 │ v2.1 │ v3.0 │
│ │ (Launch) │ (Bug fix) │ (Major) │ (Feature) │ (Major) │
│ │ │ │ │ │ │
│ │ Consumers: │ Consumers:│ Consumers:│ Consumers:│ │
│ │ App A │ App A │ App B │ App B │ │
│ │ │ │ App A │ App A │ │
│ │ │ │ │ App C │ │
│ │
│ Each consumer can choose when to upgrade │
│ │
└─────────────────────────────────────────────────────────────────────┘
Versioning Schemes
1. Path-Based Versioning
/api/v1/products
/api/v2/products
/api/v3/products
Configuration:
# Enable versioning
az apim api update \
--resource-group my-rg \
--service-name my-apim \
--name products-api \
--enable-select-or-create-version true
# Set versioning scheme
az apim api version-set create \
--resource-group my-rg \
--service-name my-apim \
--version-set-name products-versions \
--display-name "Products API Versions" \
--scheme Path \
--version-header-name "api-version" \
--version-query-name "api-version"
2. Header-Based Versioning
Header: api-version: v1
Header: api-version: v2
Policy configuration:
<inbound>
<set-variable name="apiVersion" value="@(context.Request.Headers.GetValueOrDefault("api-version", "v1"))" />
</inbound>
3. Query Parameter Versioning
/api/products?api-version=v1
/api/products?api-version=v2
Version Sets
Create Version Set
az apim api version-set create \
--resource-group my-rg \
--service-name my-apim \
--version-set-name orders-api-versions \
--display-name "Orders API" \
--description "API for managing orders" \
--scheme Path \
--version-header-name "api-version"
Version Set Structure
Version Set: Orders API
├── /orders/v1 (2023-01)
│ ├── Description: Initial version
│ └── Status: Published
├── /orders/v2 (2023-06)
│ ├── Description: Added filtering
│ └── Status: Published
├── /orders/v3 (2024-01)
│ ├── Description: New ordering features
│ └── Status: Current
└── /orders/v4-beta (2024-06)
├── Description: Preview of new features
└── Status: Preview
Managing Versions
# Create new version from existing API
az apim api create \
--resource-group my-rg \
--service-name my-apim \
--name orders-v2 \
--service-url "https://api.example.com" \
--path orders \
--api-version-set-id /subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.ApiManagement/service/my-apim/apiVersionSets/orders-api-versions
# Add to version set
az apim api update \
--resource-group my-rg \
--service-name my-apim \
--name orders-v2 \
--version-set-id /subscriptions/xxx/.../versionSets/orders-api-versions \
--api-version v2
API Revisions
Understanding Revisions
┌─────────────────────────────────────────────────────────────────────┐
│ REVISION CONCEPTS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Revision: A specific version of an API at a point in time │
│ Revision = API Version + Revision Number │
│ │
│ API: "Orders" │
│ ├── Revision 1 (v1-rev1) - Original │
│ ├── Revision 2 (v1-rev2) - Bug fixes │
│ ├── Revision 3 (v1-rev3) - New endpoint │
│ │ │
│ └──────── Current (active in production) │
│ │
│ Consumers access via: /orders;rev=3 │
│ │
└─────────────────────────────────────────────────────────────────────┘
Create Revision
# Create new revision from current
az apim api create \
--resource-group my-rg \
--service-name my-apim \
--name "orders-api;rev=2" \
--service-url "https://api.example.com" \
--path orders \
--source-api-id /subscriptions/xxx/.../apis/orders-api
Test Revision
# Test specific revision
# URL format: /path;rev=revisionNumber
https://myapim.azure-api.net/orders;rev=2
# Also via header
ocp-apim-revision: 2
Switch to Revision (Go Live)
# Make revision current/production
az apim api release create \
--resource-group my-rg \
--service-name my-apim \
--api-id "orders-api;rev=2" \
--notes "Release with bug fixes and new endpoint"
Version and Revision Best Practices
Versioning Strategy
| Strategy | When to Use | Example |
|---|---|---|
| Major versions | Breaking changes | v1 → v2 |
| Minor versions | New features | v1.0 → v1.1 |
| Internal versions | Non-breaking | v1-rev1 → v1-rev2 |
Recommended Workflow
1. Create Revision (non-breaking changes)
└── Test with ;rev=N
2. Test and validate
└── Use developer portal or Postman
3. Release Revision
└── Make current with notes
4. (If breaking) Create New Version
└── Publish as v2, v3, etc.
Deprecation Strategy
<!-- Warn about deprecated API -->
<policies>
<outbound>
<choose>
<when condition="@(context.Request.Url.Path.Contains("/v1/"))">
<set-header name="Deprecation" exists-action="override">
<value>2024-12-31</value>
</set-header>
<set-header name="Sunset" exists-action="override">
<value>Sat, 31 Dec 2024 23:59:59 GMT</value>
</set-header>
<set-header name="Link" exists-action="override">
<value><https://api.example.com/v2/docs>; rel="successor-version"</value>
</set-header>
</when>
</choose>
</outbound>
</policies>
Complete Example
Setup Versioned API
# 1. Create version set
az apim api version-set create \
--resource-group my-rg \
--service-name my-apim \
--version-set-name products-version-set \
--display-name "Products API" \
--scheme Path
# 2. Create v1 API
az apim api create \
--resource-group my-rg \
--service-name my-apim \
--name products-v1 \
--service-url "https://api-v1.example.com" \
--path products \
--api-version-set-id "/subscriptions/xxx/resourceGroups/my-rg/providers/Microsoft.ApiManagement/service/my-apim/apiVersionSets/products-version-set" \
--api-version v1
# 3. Import OpenAPI spec
az apim api import \
--resource-group my-rg \
--service-name my-apim \
--api-id products-v1 \
--specification-type OpenAPI \
--value "https://raw.githubusercontent.com/api/v1-spec.yaml"
# 4. Publish v1
az apim api update \
--resource-group my-rg \
--service-name my-apim \
--name products-v1 \
--subscription-required true
Update to v2
# 1. Create revision of v1 for testing
az apim api create \
--resource-group my-rg \
--service-name my-apim \
--name "products-v1;rev=2" \
--source-api-id /subscriptions/xxx/.../apis/products-v1
# 2. Test changes
# POST to /products;rev=2
# 3. Release revision as current v1
az apim api release create \
--resource-group my-rg \
--service-name my-apim \
--api-id "products-v1;rev=2" \
--notes "Added search endpoint"
# 4. When ready, create v2 from v1
az apim api create \
--resource-group my-rg \
--service-name my-apim \
--name products-v2 \
--source-api-id /subscriptions/xxx/.../apis/products-v1
# 5. Update v2 with breaking changes
# Import v2 spec, update policies
# 6. Publish v2
az apim api update \
--resource-group my-rg \
--service-name my-apim \
--name products-v2 \
--api-version v2
Related Topics
- Policy Engine — Advanced policy configuration
- Caching — Response caching by version
- Rate Limiting — Throttling by version
Azure Integration Hub - Intermediate Level