Стоп. Железо ни при чём. Речь про слои логики — кто рисует кнопку, кто проверяет права, кто хранит заказ.
Я сам когда-то на собесе нёс эту дичь про серверную стойку. Мидл ставил галочку «не догоняет архитектуру». Стыдно. Поэтому разложу так, чтобы кивали, а не вздыхали: раньше слоёв было два, теперь почти всегда три.
Раньше — двухслойка
Клиент и БД, между ними ничего. Клиент «толстый» — полноценное приложение со всей логикой внутри. Delphi-десктоп в банке году в 2003-м: знает строку подключения к Oracle, сам пишет SQL, лезет в базу. Часть правил — в коде клиента, часть — в хранимках (код внутри БД, исполняемый ею самой). Так жили 1С, банковские АРМы, заводские учётки.
Двухслойка не умерла: SQL Management Studio, DBeaver, Power BI, Excel с прямым коннектом — всё это она.
Откуда у трёхслойки растут ноги
Двухслойка треснула, как только из локалки полезли в большой интернет:
- Интернет. Публиковать Oracle наружу — самоубийство: любой школьник перебирает пароли по протоколу БД.
- Масштаб. Сто клиентов — сто коннектов. Сто тысяч — БД упирается в
max_connections, жрёт память и задыхается до запросов. - Обновления. Поменяли формулу скидки — а она в 5000 АРМов. Половина обновится через месяц, половина никогда. База в один день считает разное.
- Безопасность. В коде клиента — пароль от БД. Декомпилировал
.exe— забрал всё. - Платформы. Веб, мобилка, десктоп. Копировать логику на три стека — путь в ад.
Так и появился бэкенд — отдельный слой логики посередине.
Сейчас — трёхслойка
- Клиент — рисует интерфейс, держит UI-состояние. Бизнес-правил тут больше нет.
- Бэкенд (API) — вся логика, валидации, права. Stateless: ничего про тебя не помнит, поэтому любая из ста копий за балансировщиком обслужит. Контракт —
REST/gRPC/GraphQL, кто ты — по токену (JWTлибо session id вRedis). - БД — в закрытой сети, доступ только из бэкенда. Пул соединений (часто
PgBouncer) переиспользуется на тысячи клиентов.
Клиент рисует, бэк думает.
SPA на React «тонким» не назовёшь — роутинг, кэш, оптимистичные апдейты. Но суть та же. В проде слоёв обычно больше: CDN, API gateway, кэш, очереди, аналитика сбоку. Снизу всё равно та же трёхслойка.
Браузер vs нативка
Браузерные — HTML/JS, ничего не ставить, обновления мгновенные; но без интернета по умолчанию мертвы и к железу доступ ограничен. Нативные — офлайн, камера, GPS, пуши, биометрия; но релиз через сторы, а пользователь обновляется когда захочет (то есть никогда), и бэк тащит совместимость со старыми API годами. Гибриды (Electron, React Native, Flutter) — браузер или JS-движок в обёртке.
Видишь в требованиях «клиент» — сразу спрашивай: браузерный или нативный. От этого пляшет всё: оффлайн, пуши, релизы, версионирование API.
На десерт: бизнес-логика в хранимках
Это fat database — антипаттерн или норма? Защитники: «БД быстрее работает с данными, зачем гонять туда-сюда». Противники: «не тестируется, не версионируется в git, рефакторинг — боль». Если бы я сегодня собирал новый сервис — никаких хранимок с бизнес-логикой; только утилитарное (агрегации, миграции). Возраст системы легко прочитать по ответу на вопрос «у нас бизнес-логика где живёт?».