HardТеория2 min

Azure API Management

APIM-политики, rate limiting, JWT-валидация, версионирование, developer portal

API Management (APIM) -- единая точка входа (API Gateway) для всех ваших API. Обеспечивает безопасность, мониторинг, throttling и документацию.

Архитектура APIM

Клиент -> APIM Gateway -> Backend API (App Service, Functions, AKS)
              |
              +-- Policies (inbound -> backend -> outbound -> on-error)
              +-- Products (группировка API)
              +-- Developer Portal (документация)

Компоненты:

  • API Gateway -- принимает запросы, применяет политики, пересылает на backend
  • Azure Portal -- настройка API, политик, продуктов
  • Developer Portal -- автоматическая документация для разработчиков (OpenAPI/Swagger)

Политики (Policies)

Политики -- XML-инструкции, которые выполняются на каждом этапе обработки запроса.

Этапы обработки

<policies>
    <inbound>
        <!-- До отправки на backend -->
    </inbound>
    <backend>
        <!-- При вызове backend -->
    </backend>
    <outbound>
        <!-- После получения ответа от backend -->
    </outbound>
    <on-error>
        <!-- При ошибке -->
    </on-error>
</policies>

Rate Limiting

Ограничение количества запросов для защиты от перегрузки:

<policies>
    <inbound>
        <!-- 100 запросов в минуту на ключ подписки -->
        <rate-limit calls="100" renewal-period="60" />

        <!-- Или по IP-адресу -->
        <rate-limit-by-key
            calls="50"
            renewal-period="60"
            counter-key="@(context.Request.IpAddress)" />

        <!-- Квота: 10000 запросов в неделю -->
        <quota calls="10000" renewal-period="604800" />
    </inbound>
</policies>

JWT-валидация

<policies>
    <inbound>
        <validate-jwt header-name="Authorization"
                      failed-validation-httpcode="401"
                      failed-validation-error-message="Unauthorized">
            <openid-config url="https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" />
            <required-claims>
                <claim name="aud" match="all">
                    <value>{client-id}</value>
                </claim>
                <claim name="roles" match="any">
                    <value>Orders.Read</value>
                    <value>Orders.Admin</value>
                </claim>
            </required-claims>
        </validate-jwt>
    </inbound>
</policies>

Кеширование ответов

<policies>
    <inbound>
        <!-- Проверить кеш -->
        <cache-lookup vary-by-developer="false"
                      vary-by-developer-groups="false"
                      downstream-caching-type="none" />
    </inbound>
    <outbound>
        <!-- Сохранить в кеш на 5 минут -->
        <cache-store duration="300" />
    </outbound>
</policies>

Трансформация запросов

<policies>
    <inbound>
        <!-- Добавление заголовка -->
        <set-header name="X-Request-Source" exists-action="override">
            <value>APIM</value>
        </set-header>

        <!-- Изменение URL -->
        <rewrite-uri template="/api/v2/orders" />

        <!-- Установка backend -->
        <set-backend-service base-url="https://app-orderapp.azurewebsites.net" />
    </inbound>
    <outbound>
        <!-- Удаление чувствительных заголовков -->
        <set-header name="X-Powered-By" exists-action="delete" />
        <set-header name="Server" exists-action="delete" />
    </outbound>
</policies>

CORS

<policies>
    <inbound>
        <cors allow-credentials="true">
            <allowed-origins>
                <origin>https://myapp.com</origin>
            </allowed-origins>
            <allowed-methods>
                <method>GET</method>
                <method>POST</method>
            </allowed-methods>
            <allowed-headers>
                <header>Authorization</header>
                <header>Content-Type</header>
            </allowed-headers>
        </cors>
    </inbound>
</policies>

Версионирование API

APIM поддерживает несколько стратегий:

  • URL path: /api/v1/orders, /api/v2/orders
  • Query string: /api/orders?api-version=2.0
  • Header: Api-Version: 2.0

Products

Products группируют API и определяют условия доступа:

  • Open -- доступен без подписки
  • Starter -- бесплатный, с лимитами (100 запросов/мин)
  • Premium -- платный, расширенные лимиты

Уровни APIM

Уровень Описание Gateway SLA
Consumption Serverless, оплата за вызов 99.95%
Developer Для разработки, без SLA Нет SLA
Basic Базовый production 99.95%
Standard VNet, multi-region 99.95%
Premium VNet, multi-region, WAF 99.99%

Event Grid

Помимо Service Bus, Azure предоставляет Event Grid для event-driven архитектуры:

// Публикация кастомного события
var client = new EventGridPublisherClient(
    new Uri("https://topic-orderapp.eventgrid.azure.net/api/events"),
    new AzureKeyCredential(topicKey));

var events = new List<EventGridEvent>
{
    new EventGridEvent(
        subject: $"/orders/{orderId}",
        eventType: "Order.Created",
        dataVersion: "1.0",
        data: new { OrderId = orderId, Total = total })
};

await client.SendEventsAsync(events);

Event Grid vs Service Bus:

  • Event Grid -- легковесные события, реактивная архитектура, push-модель
  • Service Bus -- надежные сообщения, очереди, DLQ, транзакции, pull-модель

Проверь себя

В каком порядке выполняются секции политик APIM?

Какая политика APIM ограничивает количество запросов за период времени?

Когда лучше использовать Event Grid вместо Service Bus?

Какой уровень APIM подходит для production с поддержкой VNet?