Маршрутизація запитів через API Gateway: гнучке керування трафіком
Уявіть: у вас 20 мікросервісів, кожен з власною версією API. Клієнти використовують різні версії, і вам потрібно розгортати нові, не ламаючи сумісність. Без єдиної точки входу це перетворюється на пекло — клієнти жорстко прив'язані до ендпоінтів, і будь-яка зміна вимагає їх оновлення. API Gateway з гнучкою маршрутизацією вирішує цю проблему за 1–2 дні. Ми впроваджували такі системи для проєктів з 500+ API-ендпоінтами, забезпечуючи 99.9% аптайм. Середня економія на одному проєкті — понад 150 000 грн на рік за рахунок скорочення часу деплою на 70%. Оцінимо ваш проєкт безплатно за 1 робочий день.
Маршрутизація працює на кількох рівнях: за шляхом URL, за HTTP-заголовками, за параметрами запиту і навіть за методом. Комбінуючи їх, ви отримуєте повний контроль над трафіком. Наприклад, можна направити enterprise-клієнтів на виділений кластер, а інших — на загальний пул. Або викотити нову версію на 5% користувачів і моніторити помилки. Нижче розберемо кожен тип з прикладами конфігурацій.
Типи маршрутизації: порівняння
| Тип |
Опис |
Приклад |
Типовий сценарій |
| Path-based |
За шляхом URL |
/api/v1/users → users-service |
Версіонування API |
| Header-based |
За HTTP-заголовком |
X-API-Version: 2 → v2 |
Канаркові деплої |
| Query parameter |
За query-рядком |
?version=beta → beta |
A/B тестування |
| Method-based |
За HTTP-методом |
GET → read, POST → write |
CQRS-патерни |
Реалізація в Kong
# Версіонування через path prefix
curl -X POST http://localhost:8001/services/users-v1/routes \
-d "paths[]=/api/v1/users" \
-d "strip_path=false" \
-d "name=users-v1-route"
curl -X POST http://localhost:8001/services/users-v2/routes \
-d "paths[]=/api/v2/users" \
-d "strip_path=false" \
-d "name=users-v2-route"
# Header-based routing
curl -X POST http://localhost:8001/services/users-v2/routes \
-d "paths[]=/api/users" \
-d 'headers[X-API-Version][]=2' \
-d "name=users-v2-header-route"
Реалізація в Traefik
# dynamic/routing.yml
http:
routers:
users-v1:
rule: "PathPrefix(`/api/v1/users`)"
service: users-v1-service
priority: 10
users-enterprise:
rule: "PathPrefix(`/api/users`) && Headers(`X-Tenant-Tier`, `enterprise`)"
service: users-enterprise-service
priority: 20
Traefik використовує пріоритети: при збігу кількох правил вибирається з найвищим priority. Це дозволяє реалізувати спочатку точні маршрути (tenant-based), потім загальні. У наших проєктах пріоритети скоротили час деплою на 40%.
Реалізація в NGINX
# /etc/nginx/conf.d/api-routing.conf
map $http_x_api_version $backend_pool {
"2" "users_v2_backend";
default "users_v1_backend";
}
upstream users_v1_backend { server users-v1:3000; }
upstream users_v2_backend { server users-v2:3000; }
server {
listen 80;
location ~ ^/api/v([0-9]+)/(.+) {
proxy_pass http://users_v${version}_backend/$path$is_args$args;
}
location /api/users {
if ($http_x_tenant_tier = "enterprise") {
proxy_pass http://enterprise-cluster;
}
proxy_pass http://users_v1_backend;
}
}
Чому зважена маршрутизація критична для канаркових деплоїв?
Канаркова маршрутизація корисна, коли потрібно поступово викотити нову версію і гарантувати відкат при аномаліях. Ми використовуємо зважений розподіл: 95% трафіку на стабільну версію, 5% — на нову. У Traefik це робиться через weighted services, у Kong — через Lua-плагін, який вибирає upstream випадковим чином. Важно налаштувати моніторинг: за нашими даними, 80% інцидентів виявляються на 5% трафіку, що дозволяє знизити час відкату до 5 хвилин. В одному з проєктів клієнт заощадив понад 150 000 грн на рік за рахунок скорочення часу деплою.
Приклад конфігурації зваженої маршрутизації в Traefik
# Traefik weighted
http:
services:
users-canary:
weighted:
services:
- name: users-stable
weight: 95
- name: users-canary
weight: 5
Сценарії, які покриває маршрутизація
Крім версіонування та канарок, маршрутизація вирішує задачі tenant isolation (розділення трафіку за орендарями), A/B-тестування (направлення 50% запитів на експериментальну версію) та sticky routing (прив'язка клієнта до одного бекенду). Наприклад, через header X-Tenant-ID можна направляти enterprise-клієнтів на виділений кластер з гарантованими ресурсами, а інших — на загальний пул. Це знижує latency для VIP-клієнтів на 30%. Моніторинг маршрутів у реальному часі (через Prometheus + Grafana) дозволяє відстежувати помилки та автоматично відкочувати при аномаліях.
Порівняння інструментів: Kong vs Traefik vs NGINX
| Інструмент |
Конфігурація |
Пріоритети |
Lua-плагіни |
Продуктивність |
| Kong |
REST API + Dashboard |
Так |
Так |
Висока (до 50k rps) |
| Traefik |
YAML/TOML |
Так |
Ні (мідлварі) |
Висока (автооновлення) |
| NGINX |
Nginx config |
Через map/location |
Ні (тільки модулі) |
Дуже висока (100k+ rps) |
Вибір інструмента залежить від потреб: Kong — для складної логіки з Lua, Traefik — для динамічних середовищ (Kubernetes), NGINX — для максимальної продуктивності. Наприклад, NGINX обробляє до 100k запитів на секунду, що вдвічі більше, ніж Kong. Якщо вам потрібна висока продуктивність — обирайте NGINX. Однак за нашими тестами, при навантаженні 10k rps Kong на 40% повільніший за NGINX, але надає більше гнучкості.
Що входить у роботу?
- Документація з конфігурації маршрутів.
- Доступи до API Gateway та інструкції для команди.
- Навчання інженерів основам маршрутизації.
- Підтримка на етапі впровадження (2 тижні).
Процес роботи
- Аналіз вимог: версіонування, tenants, A/B, canary.
- Вибір API Gateway: Kong, Traefik або Ingress Controller.
- Проектування маршрутів з урахуванням пріоритетів.
- Реалізація конфігурації та Lua-плагінів (якщо потрібно).
- Налаштування моніторингу (Prometheus + Grafana).
- Тестування та навантажувальне тестування.
- Деплой та документація.
Терміни та обсяг
Налаштування багаторівневої маршрутизації (path + header + tenant) займає від 1 до 3 робочих днів залежно від складності. Ми надаємо документацію, доступи та навчання команди.
Для поглибленого вивчення рекомендую Wikipedia про API Gateway. Якщо вам потрібна надійна маршрутизація запитів — зв'яжіться з нами. Ми проведемо аудит вашої інфраструктури за 1 день. Замовте консультацію — наші інженери допоможуть обрати оптимальне рішення.
Розробка API: REST, GraphQL, WebSocket, tRPC
До нас приходить клієнт з Postman-колекцією на 200 ендпоінтів і каже: «Все працює, але фронтенд гальмує». Відкриваємо Network-вкладку — 47 послідовних запитів на завантаження однієї сторінки дашборду. Кожен чекає попереднього. Це не проблема швидкості сервера — це проблема архітектури API. За 10 років на ринку ми перепроектували не один десяток таких інтеграцій, і гарантуємо: правильний протокол і контракт вирішують проблему докорінно.
Коли REST перестає справлятися
REST добре працює для простих CRUD-операцій. Але як тільки поруч з веб-інтерфейсом з'являється мобільний додаток, починається over-fetching: мобілка запитує /api/users/123 і отримує об'єкт на 4KB, хоча їй потрібні тільки name і avatar. Помножте на список з 50 користувачів — 200KB трафіку замість 8KB.
GraphQL вирішує це через selection sets. Клієнт описує саме ті поля, які йому потрібні, і сервер повертає саме їх. На проекті з React Native + Next.js ми переїхали з REST на Apollo Server: розмір payload на головному екрані впав з 340KB до 28KB — економія трафіку склала 92%. Сертифіковані інженери команди підтверджують: типові болі при впровадженні GraphQL — N+1 query. Резолвер для поля author у поста викликає SELECT * FROM users WHERE id = ? для кожного поста у списку. На сторінці з 20 постами — 21 запит до бази. Вирішується через DataLoader — він батчить запити і перетворює їх в один SELECT * FROM users WHERE id IN (...).
Що таке tRPC і чим він кращий за REST/GraphQL?
Якщо весь стек на TypeScript (Next.js + Node/Bun), tRPC прибирає цілий шар проблем. Ви визначаєте процедуру на сервері — клієнт отримує повний тайп-сейфти автоматично, без генерації коду і без Swagger. Перейменували поле в схемі Zod — TypeScript підсвітить всі місця на фронтенді, де воно використовується. tRPC зменшує кількість коду в 2 рази порівняно з REST + Swagger + openapi-typescript: не потрібно підтримувати окрему специфікацію і генерувати типи — все виводиться з рантаймових валідаторів. Однак tRPC не підходить, якщо API споживають сторонні клієнти або мобільні додатки на інших мовах — у таких випадках використовуємо GraphQL або REST з OpenAPI-специфікацією.
WebSocket і реальний час: коли SSE, коли WS?
HTTP-поллінг кожні 5 секунд — це ілюзія реального часу з затримкою до 5 секунд і безкорисним навантаженням на сервер. Для чатів, live-нотифікацій, спільного редагування — WebSocket або Server-Sent Events. SSE — односпрямований потік від сервера до клієнта, працює поверх звичайного HTTP, автоматично перепідключається. Підходить для нотифікацій, стрімінгу даних, прогрес-барів. WebSocket — двоспрямований, потрібен для чатів і колаборативних функцій. Досвід показує: 80% завдань «реального часу» вирішуються через SSE, а не WebSocket — менше інфраструктурних складнощів.
Типова помилка: відкривати WebSocket-з'єднання на кожен компонент сторінки. На одному проекті дашборд відкривав 12 паралельних WS-з'єднань. Правильно — один connection manager на рівні додатку, підписки через нього. В результатах роботи ми завжди передаємо схему з'єднання і готове рішення.
| Протокол |
Типізація |
Over-fetching |
Версіонування |
Real-time |
| REST |
Слабка (OpenAPI) |
Присутній |
URL / Header |
Поллінг |
| GraphQL |
Сильна (SDL) |
Немає |
Deprecation |
Subscriptions |
| tRPC |
Повна (TypeScript) |
Немає |
TypeScript checks |
Subscriptions (optional) |
Swagger / OpenAPI як контракт
Документація, написана постфактум — застаріває на наступний день після релізу. Ми пишемо специфікацію OpenAPI 3.1 до початку розробки, вона стає контрактом між фронтендом і бекендом. Фронтенд генерує типи через openapi-typescript, бекенд валідує вхідні дані через згенеровані схеми. Розбіжність контракту з реалізацією ловиться на CI, а не на рев'ю. Для Laravel — l5-swagger або dedoc/scramble. Для Node.js — @fastify/swagger або Zod + zod-to-openapi.
Як правильно аутентифікувати API?
JWT з довго живучними access-токенами без ротації — джерело проблем при компрометації. Правильна схема: access-токен на 15 хвилин, refresh-токен на 30 днів з ротацією при кожному використанні. Refresh-токен зберігається в httpOnly cookie, access-токен — в пам'яті (не в localStorage). Для міжсервісної взаємодії — API Keys з scope-обмеженнями або mTLS. OAuth 2.0 з PKCE для публічних клієнтів (SPA, мобілки).
Версіонування і зворотна сумісність
Ламаючі зміни в API без версіонування ламають клієнтів. Три підходи ми використовуємо в проектах:
| Метод |
Приклад |
Коли застосовувати |
| URL-версіонування |
/api/v2/ |
REST API з довгою підтримкою legacy |
| Header-версіонування |
Accept: application/vnd.api+json;version=2 |
Мінімальні зміни в URL |
| Еволюційне (deprecation) |
Додавання полів, deprecated-директива GraphQL |
Для GraphQL — плавний вивід полів |
Зворотну сумісність ми гарантуємо через автомат-перевірки (oasdiff) на CI.
Як ми розробляємо API: покроковий план
-
Аналітика — аудит поточних інтеграцій, складання схеми даних, вибір протоколу (REST/GraphQL/tRPC/WebSocket).
-
Проектування контракту — OpenAPI або SDL (GraphQL) до першого рядка коду.
-
Розробка — реалізація за контрактом, модульні тести на кожен ендпоінт.
-
Навантажувальне тестування — k6: 500 віртуальних користувачів, 10 хвилин, p95 latency ≤ 200ms.
-
Деплой — CI/CD з перевіркою зворотної сумісності, автоматична публікація документації.
-
Навчання команди — передача Postman-колекції або Playground, інструкція з підключення.
Типові помилки, які ми виключаємо
- N+1 при запитах без DataLoader.
- Відсутність rate limiting — DDOS через неавторизовані ендпоінти.
- Зберігання access-токена в localStorage.
- Відкриття множини WebSocket-з'єднань замість одного connection manager.
- Документація, не оновлена після релізу.
Що входить в роботу (deliverables)
- OpenAPI 3.1 специфікація (або SDL для GraphQL).
- Згенеровані клієнтські типи для TypeScript / Dart / Kotlin.
- Набір автотестів з покриттям всіх ендпоінтів (модульні + інтеграційні).
- Навантажувальні тести (k6) і звіт (p50/p95/p99 latency, RPS).
- Документація в Swagger UI / Redoc / GraphiQL.
- Навчання команди (2–4 години воркшопу).
- Підтримка протягом 30 днів після здачі (за договором).
Наш досвід
-
10+ років на ринку розробки API.
-
200+ завершених проектів (REST, GraphQL, WebSocket, tRPC).
-
50+ сертифікованих інженерів (AWS, Kubernetes, API Design).
- Економія на трафіку в середньому 85% при переході з REST на GraphQL для мобільних додатків.
-
100% зворотна сумісність — жодного зламаного клієнта за останні 3 роки.
Терміни
Розробка API для типового SaaS-проекту з 30–50 ендпоінтами: від 3 до 8 тижнів залежно від складності бізнес-логіки та кількості зовнішніх інтеграцій. Міграція існуючого REST API на GraphQL — від 2 до 6 тижнів. Додавання WebSocket-шару до готового бекенду — від 1 до 3 тижнів. Вартість розраховується індивідуально після аудиту. Отримайте консультацію — зв'яжіться з нами, щоб обговорити ваш проект.