API-шлюз і маршрутизація
1) Роль API-шлюзу в архітектурі
API-шлюз - L7-компонент на кордоні (edge), який:- приймає вхідний трафік (HTTP/HTTP2/HTTP3, WebSocket, gRPC);
- маршрутизує за правилами (host/path/headers/method/query/geo/ваги/здоров'я);
- застосовує наскрізні політики: автентифікація/авторизація, rate limiting, WAF, CORS, кешування;
- виконує трансформації (нормалізація заголовків/тіл, gRPC↔JSON, GraphQL stitching);
- забезпечує стійкість (timeouts, retries, circuit-breaker, outlier detection);
- дає спостережуваність і білінг (логи, метрики, трасування, квоти);
- ізолює внутрішню топологію (service mesh, приватні сервіси).
Часто використовується в парі: Edge/API-Gateway + Ingress/Mesh (Envoy/Istio/Linkerd) - перший вирішує зовнішню політику, другий - east-west.
2) Типові топології
Єдиний глобальний шлюз (CDN/edge POP → L7 gateway → сервіси) - просто, централізовані політики.
Регіональні шлюзи (per-region) + розумна маршрутизація по гео/латентності.
Multi-tenant: виділені маршрути/піддомени/ключі, квоти та ліміти на орендаря.
Hybrid: on-prem + cloud, private link/peering, приватні бекенди за API-шлюзом.
3) Правила маршрутизації L7
Критерії:- Host/Path: `api. example. com` → `/v1/orders/`.
- Headers: `X-Client`, `X-Region`, `User-Agent`, `Accept`.
- Method/Content-Type: розрізнення JSON/Proto/GraphQL.
- Query/Fragment: обережно - впливає на кеш/варіанти.
- Geo/Latency: найближчий РОР/регіон, failover при деградації.
- Weighted/Canary: розподіл трафіку 90/10, 50/50, sticky по cookie.
- Session affinity: hash-based по ключу/токену (акуратно при масштабуванні).
yaml nginx. ingress. kubernetes. io/canary: "true"
nginx. ingress. kubernetes. io/canary-weight: "10" # 10% traffic to new backend
Приклад (Envoy, header-based routing):
yaml match: { prefix: "/orders", headers: [{name: "X-Experiment", exact_match: "new"}] }
route: { cluster: orders-v2 }
4) Протоколи та сумісність
REST/JSON - дефолт, описуйте OpenAPI для валідації/генерації клієнтів.
gRPC - бінарний Proto поверх HTTP/2; для зовнішніх клієнтів використовуйте gRPC-JSON transcoding.
GraphQL - агрегує сервіси; на периметрі контролюйте complexity/глибину запитів.
WebSocket/SSE - двонаправно/пуш; враховуйте sticky і timeouts.
HTTP/2/3 (QUIC) - мультиплексування/швидкий старт; перевірте сумісність з WAF/проксі.
5) Безпека: автентифікація та авторизація
5. 1 Транспорт
TLS 1. 2 + на периметрі, HSTS, OCSP stapling, PFS.
mTLS для В2В/внутрішніх API і машин-к-машині.
IP allowlist/denylist, гео-обмеження.
5. 2 Прикладний рівень
OAuth2/OIDC: bearer-токени JWT, перевірка підпису/експірації/аудиторії.
НМАС/підписи: дата + канонізований рядок + підпис (AWS-подібно) - захист від підміни, повтору (nonce/тайм-вікно).
API-ключі: тільки як ідентифікатор; права - через RBAC/ABAC/скоупи.
CORS: явні allow-origin, пре-флайт кеш.
WAF: сигнатури (OWASP API Top 10), анормалія, бот-захист, рекурсивні JSON-поля.
DDoS/Abuse: connection limiting, token-bucket/Leaky bucket, берст + середня швидкість, динамічні бани.
yaml plugins:
- name: oidc config: { issuer: "...", client_id: "...", client_secret: "...", scopes: ["orders. read"] }
- name: rate-limiting config: { minute: 600, policy: local }
6) Валідація, трансформації та сумісність
Схеми: валідація тіла/заголовків/параметрів за OpenAPI/JSON-Schema/Protobuf.
Трансформації: нормалізація полів, маскування PII, додавання кореляційних заголовків («traceparent», «x-request-id»).
Версіонування: `Header: X-API-Version', префікси '/v1', ресурсо-версіонування; deprecation policy и Sunset.
Backward-compat: тільки add-поле; уникайте «ламаючих» змін без нової версії.
Idempotency: `Idempotency-Key` для POST; gateway зберігає ключі в Redis з TTL.
7) Стійкість: політики з'єднань
Timeouts: connect/read/write; розумні дефолти (наприклад, 1s/5s/5s).
Retries: тільки для безпечних та ідемпотентних; джиттер, exponential backoff, максимум спроб.
Circuit breaker: відкривати при помилках/латентності; half-open для проб.
Outlier detection: виведення поганих інстансів з пулу.
Bulkhead/конкуренція: ліміти на одночасні запити per-route.
Failover: активний/пасивний, зональна деградація.
Shadow traffic: «сірий» прогін V2 паралельно V1 (без впливу на відповідь) для порівняння.
yaml circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 1024 max_pending_requests: 2048 max_retries: 3
8) Кешування і продуктивність
HTTP-кеш: `Cache-Control`, `ETag/If-None-Match`, `Vary`, `stale-while-revalidate`.
Edge-кеші/РОР: CDN для статики і «кешованих» API (ідемпотентні GET).
Compression: 'gzip/br'( не стискайте вже стиснене).
Request collapsing («coalescing»): об'єднання ідентичних паралельних запитів.
Response shaping: поля/фільтри, пагінація (cursor-based), ліміти розмірів.
9) Спостережуваність і експлуатація
Метрики: `l7_req_total{route,method,code}`, `latency_ms{p50,p95,p99}`, `upstream_errors`, `retry_count`, `cb_state`, `429_rate`, `quota_usage{tenant}`.
Логи: структурні, з'trace _ id/span _ id','user _ id/tenant _ id','client _ ip'.
Трейси: W3C Trace Context («traceparent», «tracestate»), пропагуйте в апстріми.
Аудит: хто викликав що, з якими правами; незмінні сховища для чутливих API.
SLO/SLA: цільові p99, бюджет помилок; роут-рівень краще, ніж глобальний.
10) Управління планом пропускної здатності
Quota per-tenant/ключ/пул клієнтів, в хв/год/добу.
Burst + sustained ліміти; leaky bucket для згладжування.
Fairness: при перевантаженні - fair queuing замість «першого зустрівся».
Пріоритети: системні/критичні маршрути з пріоритетом і виділеними пулами.
11) Управління змінами та релізи
Canary/Blue-Green: вагова маршрутизація; автоматичне просування по SLO (помилки/латентність).
Feature gates/бекенд-прапори: включення по заголовку/токену.
Shadowing/диф-валідатори: порівняння тіл/статусів, допуски по дельті.
Стейджинги: виділені домени/шляхи ('staging. api...'), окремі ключі і квоти.
12) Приклади конфігурацій
12. 1 NGINX - базовий gateway з лімітом і кешем
nginx map $http_x_request_id $reqid { default $request_id; }
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
server {
listen 443 ssl http2;
server_name api. example. com;
security add_header Strict-Transport-Security "max-age = 31536000" always;
location /v1/ {
limit_req zone=perip burst=30 nodelay;
proxy_set_header X-Request-ID $reqid;
proxy_set_header Authorization $http_authorization;
proxy_connect_timeout 1s;
proxy_read_timeout 5s;
proxy_cache api_cache;
proxy_cache_valid 200 10s;
proxy_cache_use_stale error timeout updating;
proxy_pass http://orders-v1;
}
}
12. 2 Envoy - маршрутизація по вагах і ретраї
yaml routes:
- match: { prefix: "/orders" }
route:
weighted_clusters:
clusters:
- name: orders-v1 weight: 90
- name: orders-v2 weight: 10 retry_policy:
retry_on: "5xx,reset,connect-failure"
num_retries: 2 per_try_timeout: 2s
12. 3 Traefik - мідлварі та хедери
yaml http:
middlewares:
secHeaders:
headers:
stsSeconds: 31536000 contentTypeNosniff: true routers:
api:
rule: "Host(`api. example. com`) && PathPrefix(`/v1`)"
service: svc-orders middlewares: ["secHeaders"]
13) Анти-патерни
Один глобальний ліміт на всіх - «добрі сусіди» страждають через «галасливі».
Ретраї без ідемпотентності → дублі ефектів (платежі, створення сутностей).
Ігнорування'timeout '/' max body size'→ зависання/вичерпання воркерів.
Змішування edge-політик і бізнес-логіки в шлюзі (обважнення периметра).
Відсутність валідації схем → крихкість клієнтів і «ламаючі» релізи.
Голий WebSocket без урахування auth/лімітів/idle-тайму.
Секрети в заголовках без ротації; відсутність mTLS у внутрішніх B2B.
14) Тест-плейбуки (Game Days)
Шторм запитів: перевірка limiter/quota, 429-поведінка, деградація.
Втрата одного кластера: failover/перероздача ваги; SLO канарок.
Обважнені відповіді: max body/timeouts; обрубування з'єднань.
Ін'єкції/аномалії: WAF-правила, заборона рекурсивних JSON, великі глибини GraphQL.
Збій трасування: перевірка пропагандації «traceparent» і семплювання.
Секрети: ротація ключів/JWKS, закінчення токенів, clock-skew допуск.
15) Чек-лист впровадження
- Визначені домени/шляхи/версії, опублікована OpenAPI/Proto.
- Налаштовані TLS/mTLS, HSTS, секрет-менеджмент і ротація.
- Включені автентифікація (OIDC/HMAC), RBAC/скоупи, CORS.
- Ліміти/квоти per-tenant, справедливі черги, 429-UX.
- Маршрутизація по вагах/заголовках, план канарок і rollback.
- Політики timeout/retry/circuit-breaker/outlier.
- Валідація схем, трансформації, маскування PII.
- Edge-кеш/ETag, coalescing, gzip/br.
- Спостережуваність: метрики, логи, траси, дашборди та алерти.
- Runbooks: інциденти, ротація ключів, блок-листи, «чорна п'ятниця».
16) FAQ
Q: Чим API-шлюз відрізняється від сервіс-міша?
A: Шлюз - north-south (зовнішній периметр, наскрізні політики). Меш - east-west (внутрішньокластерна зв'язність/MTLS/ретраї). Часто використовуються разом.
Q: Де реалізовувати auth: в шлюзі або сервісах?
A: Обидва рівні: шлюз - coarse-grained (автентифікація, базові права/квоти), сервіс - fine-grained (доменні ролі/атрибути).
Q: Коли потрібен gRPC-JSON transcoding?
A: Коли внутрішній gRPC, а назовні потрібно REST/JSON і прості клієнти/браузери.
Q: Як вибрати стратегію версіонування?
A: Для публічних API - шлях '/vN'+ заголовки депривації і довгий overlap. Для внутрішніх - capability-прапори/схема сумісності.
17) Підсумки
API-шлюз - не просто «проксик», а центр політик і стійкості. Правильна маршрутизація, безпека, ліміти, валідація і спостережуваність дають передбачуваність і швидкість релізів. Комбінуйте edge-шлюз з сервіс-мішем, автоматизуйте канарки і квоти, тестуйте збої - і периметр стане вашим прискорювачем, а не пляшковим горлечком.