API Gateway
API Gateway — промежуточный сервер, который принимает все входящие запросы клиентов и маршрутизирует их к нужным внутренним микросервисам.
Зачем нужно
В микросервисной архитектуре клиент не должен знать адреса десятков сервисов. Gateway объединяет их за единой точкой входа и берёт на себя сквозные задачи: аутентификацию, rate limiting, логирование, кэширование. Это упрощает клиентский код и позволяет менять внутреннюю архитектуру независимо от внешнего API.
Где используется
- Микросервисные бэкенды (AWS API Gateway, Kong, Nginx)
- BFF (Backend For Frontend) — отдельный gateway для каждого клиента (web/mobile)
- Публичные API-платформы с ключами доступа и тарификацией
- Aggregation — одним запросом клиент получает данные из нескольких сервисов
Функции API Gateway
Маршрутизация запросов
Клиент
│
▼
API Gateway (:443)
├── /api/users ──────────────▶ User Service (:3001)
├── /api/orders ──────────────▶ Order Service (:3002)
├── /api/products ────────────▶ Product Service (:3003)
└── /api/notifications ───────▶ Notification Service (:3004)
Аутентификация и авторизация
# Клиент отправляет JWT
GET /api/orders/42
Authorization: Bearer eyJhbG...
# Gateway проверяет токен, затем пересылает запрос
# внутренним сервисам с заголовком идентификации
X-User-Id: 99
X-User-Role: admin
Rate Limiting
# Конфигурация Nginx (пример)
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/m;
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
Агрегация (BFF-паттерн)
// Gateway объединяет ответы нескольких сервисов в один
async function getUserDashboard(userId) {
const [profile, orders, notifications] = await Promise.all([
fetch(`http://user-service/users/${userId}`),
fetch(`http://order-service/orders?userId=${userId}`),
fetch(`http://notification-service/unread?userId=${userId}`),
]);
return {
profile: await profile.json(),
orders: await orders.json(),
notifications: await notifications.json(),
};
}
Трансформация ответов
// Gateway может преобразовывать ответ под нужды клиента
// Например, переименовывать поля или фильтровать данные
app.get('/api/users/:id', async (req, res) => {
const internal = await userService.get(req.params.id);
res.json({
id: internal.user_id, // snake_case → camelCase
name: internal.full_name,
// internal.password — не передаём клиенту
});
});
Частые ошибки
- Слишком толстый Gateway — бизнес-логика переезжает в него вместо сервисов
- Single Point of Failure — нет горизонтального масштабирования Gateway
- Отсутствие circuit breaker — один упавший сервис "вешает" все запросы через Gateway
- Gateway знает о схемах БД внутренних сервисов (утечка абстракции)