Azure API Management: Gateway Patterns for Microservices
Azure API Management sits between your clients and your backend services, handling authentication, rate limiting, transformation, and monitoring. After implementing APIM as the gateway for a microservice-based integration platform, here's what I learned about making it work in practice.
Why an API Gateway?
When you have multiple microservices, each with its own API, clients face:
- Multiple endpoints to discover and manage
- Inconsistent authentication across services
- No centralized rate limiting or throttling
- Duplicated cross-cutting concerns in every service
An API gateway solves these by providing a single entry point:
Client → API Management → Service A
→ Service B
→ Service CSetting Up Products and Subscriptions
APIM organizes APIs into products. Each product has its own subscription keys, rate limits, and access policies:
<!-- product policy: 100 calls per minute, 1000 per hour -->
<rate-limit calls="100" renewal-period="60" />
<quota calls="1000" renewal-period="3600" />In our integration platform, we created separate products for each consuming application:
- **CRM Integration** — higher rate limits, access to customer and order APIs
- **Reporting** — read-only access, lower priority, access to analytics APIs
- **Partner Portal** — limited access, strict rate limiting
Inbound Policies for Message Validation
One of the most valuable patterns: validating request payloads at the gateway before they reach your services.
<inbound>
<validate-content
unspecified-content-type-action="prevent"
max-size="102400"
size-exceeded-action="prevent"
errors-variable-name="validationErrors">
<content type="application/json"
validate-as="json"
action="prevent"
schema-id="order-schema" />
</validate-content>
</inbound>This catches malformed requests before they waste compute on your backend services. In our case, it eliminated 15% of error responses that were caused by invalid payloads from a partner system.
Request Transformation
Different consumers often need different data formats. Instead of building transformation logic into each service, handle it at the gateway:
<outbound>
<set-body>@{
var body = context.Response.Body.As<JObject>();
// transform snake_case to camelCase for legacy consumer
return JsonConvert.SerializeObject(body,
new JsonSerializerSettings {
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}</set-body>
</outbound>Caching for Read-Heavy APIs
For APIs with high read-to-write ratios, APIM's built-in caching dramatically reduces backend load:
<inbound>
<cache-lookup vary-by-developer="false"
vary-by-developer-groups="false"
vary-by-query-parameter="status,category"
caching-type="internal">
<vary-by-header>Accept</vary-by-header>
</cache-lookup>
</inbound>
<outbound>
<cache-store duration="300" />
</outbound>In our reporting APIs, this reduced backend calls by 80% during peak hours.
Monitoring and Diagnostics
APIM integrates with Application Insights for request-level telemetry:
<inbound>
<set-header name="X-Correlation-Id" exists-action="skip">
<value>@(context.RequestId.ToString())</value>
</set-header>
<trace source="gateway"
severity="information">
<message>@($"Request from {context.Subscription.Name}")</message>
</trace>
</inbound>Every request gets a correlation ID that flows through to backend services, making distributed tracing across the entire pipeline possible.
Versioning Strategy
APIs evolve. APIM supports multiple versioning schemes — we use URL path versioning:
/api/v1/orders → Backend v1
/api/v2/orders → Backend v2Both versions can run simultaneously. When a consumer migrates to v2, we don't break their existing integration. When all consumers have migrated, we deprecate v1 with a sunset header:
<outbound>
<set-header name="Sunset" exists-action="override">
<value>Sat, 01 Mar 2026 00:00:00 GMT</value>
</set-header>
</outbound>Key Takeaways
- Use APIM products to group APIs by consumer and apply different policies
- Validate payloads at the gateway to protect backend services
- Leverage caching for read-heavy APIs — the savings are significant
- Correlation IDs and Application Insights integration are essential for debugging
- Plan for API versioning from day one — consumers will thank you
Share this article
About the Author
Georg is a senior solution architect specializing in .NET, Azure, and Dynamics 365. He helps organizations design and build scalable, maintainable enterprise systems. When he's not writing code, he's writing about it here.
Learn more about Georg