# API и шлюзы

← [Раздел](README.md) · [Главная](../README.md)

## Цель

Понять роль **API** как контракта между клиентом и сервером, разницу стилей **REST** и введение в **API Gateway** — единую точку входа в облако.

## Предварительно

- [Слои приложения](sloi-prilozheniya.md)

## Время

**3–4 часа**

---

## Что такое API в облаке

**API (Application Programming Interface)** — описание того, **как** клиент запрашивает действия у сервера: URL, метод, формат тела, ответы и ошибки.

Для «Умного списка» примеры:

| Метод | Путь | Смысл |
|-------|------|-------|
| GET | `/v1/lists` | Список всех списков пользователя |
| POST | `/v1/lists` | Создать список |
| POST | `/v1/lists/{id}/items` | Добавить пункт |
| DELETE | `/v1/items/{id}` | Удалить пункт |

Клиент **не знает**, PostgreSQL это или MongoDB — только контракт API.

---

## REST — распространённый стиль

**REST** опирается на HTTP:

| HTTP метод | Обычно значит |
|------------|---------------|
| GET | Прочитать (без побочных эффектов) |
| POST | Создать ресурс или действие |
| PUT/PATCH | Обновить |
| DELETE | Удалить |

**Коды ответа:**

| Код | Когда |
|-----|-------|
| 200 | Успех с телом |
| 201 | Создано |
| 400 | Ошибка клиента (валидация) |
| 401 | Не авторизован |
| 403 | Нет прав |
| 404 | Не найдено |
| 500 | Ошибка сервера |

Пример ответа об ошибке (единый формат — хорошая практика):

```json
{
  "success": false,
  "data": null,
  "error": "List not found",
  "meta": { "request_id": "abc-123" }
}
```

Подробнее о контрактах — [раздел 04](../04-vzaimodeistvie/kontrakty-api.md).

---

## Альтернативы REST (кратко)

| Стиль | Когда уместен |
|-------|---------------|
| **GraphQL** | Мобильному клиенту нужны выборочные поля, много экранов |
| **gRPC** | Внутренняя связь сервисов, низкая latency, строгие контракты |
| **WebSocket** | Чат, live-обновления списка без polling |

Новичку достаточно **уверенного REST**; остальное — по мере необходимости.

---

## Внутренние vs внешние API

```mermaid
flowchart LR
  Mobile[Mobile] --> Public[Public API]
  Web[Web] --> Public
  Public --> GW[API Gateway]
  GW --> Lists[Svc Lists]
  GW --> Users[Svc Users]
  Lists -->|gRPC internal| Users
```

| Тип | Кто вызывает | Требования |
|-----|--------------|------------|
| **Public** | Интернет, партнёры | Строгая версия, rate limit, WAF |
| **Internal** | Другие сервисы в VPC | mTLS, private network |
| **Admin** | Операторы | VPN, отдельный auth |

---

## API Gateway — зачем

**API Gateway** — reverse proxy с политиками на границе:

| Функция | Пример |
|---------|--------|
| Маршрутизация | `/users/*` → сервис users |
| TLS termination | HTTPS снаружи, HTTP внутри mesh |
| Аутентификация | Проверка JWT на входе |
| Rate limiting | 100 req/min на API key |
| CORS | Разрешить `https://app.example.com` |
| Агрегация | Один запрос → несколько backend (осторожно) |

Без шлюза каждый микросервис дублировал бы TLS, CORS и лимиты — **дрейф конфигурации**.

```mermaid
flowchart TB
  Internet[Интернет] --> GW[API Gateway]
  GW --> A[Service A]
  GW --> B[Service B]
  GW --> C[Service C]
```

Примеры категорий: Kong, AWS API Gateway, NGINX Ingress (в K8s), Envoy.

---

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

Публичный API **ломать нельзя** без предупреждения:

| Подход | Как |
|--------|-----|
| URL | `/v1/lists`, `/v2/lists` |
| Header | `Accept: application/vnd.app.v2+json` |
| Query | редко, `?version=2` |

Правило: **добавляйте** поля, не удаляйте; deprecated — с датой отключения.

---

## Документация API

| Формат | Назначение |
|--------|------------|
| OpenAPI (Swagger) | Машиночитаемое описание REST |
| Postman Collection | Ручные тесты |
| Примеры curl | Быстрый старт для разработчиков |

OpenAPI генерирует **клиентский SDK** и **мок-сервер** для frontend без готового backend.

---

## Безопасность на границе API

- Только **HTTPS** в проде  
- Токены (Bearer JWT) или session cookies — не пароль в каждом запросе  
- **Никогда** не отдавать stack trace в 500 клиенту  
- Идемпотентность для POST оплаты: заголовок `Idempotency-Key`  

Детали — [раздел 05](../05-bezopasnost/README.md).

---

## Практика

1. Спроектируйте 5 endpoints для учебного списка (таблица метод/путь/тело).  
2. Для каждого укажите ожидаемый HTTP-код успеха и одну ошибку.  
3. Нарисуйте схему: 2 микросервиса за одним Gateway.

---

## Самопроверка

1. Чем 401 отличается от 403?  
2. Зачем версия в URL `/v1/`?  
3. Назовите три функции API Gateway.

---

## Дальше

→ [Базы и хранилища](bazy-i-hranilishcha.md)
