# Слои приложения

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

## Цель

Понять **многослойную** структуру облачного приложения: презентация, API, бизнес-логика, доступ к данным — и зачем разделять ответственность между слоями.

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

- [Оглавление раздела 02](README.md)
- [Что такое облачное приложение](../01-osnovy/chto-takoe-oblachnoe-prilozhenie.md)

## Время

**3–4 часа**

---

## Зачем слои

**Слой** — логическая группа кода с **одной ответственностью**. Разделение даёт:

- проще **тестировать** бизнес-логику без HTTP;
- проще **менять** UI без переписывания БД;
- проще **масштабировать** только горячий слой (часто API).

Без слоёв «всё в одном файле» быстро становится нечитаемым при >5 разработчиках.

---

## Классическая схема (веб и mobile)

```mermaid
flowchart TB
  subgraph presentation [Презентация]
    UI[Веб / Mobile UI]
  end
  subgraph api_layer [API слой]
    REST[REST / GraphQL handlers]
  end
  subgraph business [Бизнес-логика]
    Domain[Сервисы / use cases]
  end
  subgraph data [Данные]
    Repo[Репозитории]
    DB[(БД)]
  end
  UI -->|HTTPS JSON| REST
  REST --> Domain
  Domain --> Repo
  Repo --> DB
```

| Слой | Делает | Не делает |
|------|--------|-----------|
| Презентация | Отображение, ввод, локальный UX | Прямой SQL к прод-БД |
| API | Маршруты, валидация входа, коды HTTP | Сложные бизнес-правила без делегирования |
| Бизнес-логика | Правила: «нельзя удалить чужой список» | Знание про HTML и кнопки |
| Данные | CRUD, транзакции, маппинг | Решение продуктовых сценариев |

---

## Пример: удаление пункта списка

1. **UI:** пользователь нажал «удалить», отправил `DELETE /items/42`.  
2. **API:** проверил JWT, распарсил id.  
3. **Domain:** `ListService.deleteItem(userId, 42)` — проверка владельца.  
4. **Repo:** `DELETE FROM items WHERE id=42`.  

Если правило «только владелец» окажется в UI — мобильное приложение и веб **разъедутся**; если только в SQL-триггере — сложно тестировать.

---

## Трёхзвенная архитектура (3-tier)

Исторический термин, всё ещё полезный:

| Tier | В облаке |
|------|----------|
| Presentation | CDN + SPA / mobile |
| Application | Stateless API за LB |
| Data | Managed DB, replicas |

```mermaid
flowchart LR
  Browser[Браузер] --> LB[Load Balancer]
  LB --> App1[API 1]
  LB --> App2[API 2]
  App1 --> DB[(Primary DB)]
  App2 --> DB
  DB --> Replica[(Read replica)]
```

Read replica — копия для **чтения**; запись обычно в primary. Тема масштаба — [раздел 06](../06-masshtabirovanie/README.md).

---

## Frontend vs Backend

| Термин | Где выполняется |
|--------|-----------------|
| **Frontend** | Браузер или приложение на устройстве |
| **Backend** | Серверы в облаке |

**BFF (Backend for Frontend)** — отдельный тонкий API под мобильное приложение, если общий backend отдаёт «лишнее» для телефона. Не обязателен на старте.

---

## Горизонтальные «срезы»

Помимо вертикальных слоёв есть **модули по фичам**:

- `users` — регистрация, профиль  
- `lists` — CRUD списков  
- `sharing` — приглашения  

В монолите модули — пакеты в одном деплое. В микросервисах — отдельные сервисы с **своей** БД (идеально).

---

## Антипаттерны

| Антипаттерн | Проблема |
|-------------|----------|
| **Smart UI** | Вся логика в React-компонентах |
| **Anemic domain** | Сервисы только проксируют в БД без правил |
| **Leaky abstraction** | API отдаёт сырой SQL-ошибки клиенту |
| **God service** | Один класс на 5000 строк |

---

## Слой интеграций

Часто выделяют **адаптеры** к внешним системам:

| Интеграция | Адаптер |
|------------|---------|
| Email SaaS | `EmailSender` interface |
| Платежи | `PaymentGateway` |
| Карты | `GeoProvider` |

Бизнес-логика зависит от **интерфейса**, не от конкретного вендора — проще менять Stripe на другого провайдера в тестах.

---

## Практика

1. Для «добавить пункт в список» распишите, что делает каждый из 4 слоёв (4–5 пунктов).  
2. Найдите в открытом pet-проекте на GitHub, где смешаны UI и SQL (если есть) — почему это риск.

---

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

1. Почему бизнес-правила не должны жить только во frontend?  
2. Чем tier «Application» отличается от «Presentation»?  
3. Что такое репозиторий в слое данных одной фразой?

---

## Дальше

→ [API и шлюзы](api-i-shlyuzy.md)
