Обзор раздела: NestJS и API
Ты прошёл Node.js изнутри: Event Loop, стримы, модули CJS/ESM. Теперь самое время ответить на вопрос, который отделяет «пишу скрипты на Node» от «строю backend-приложение»: как организовать код так, чтобы он не рассыпался через полгода и чтобы новый разработчик сел в проект за день, а не за месяц.
Этот раздел — про четыре вещи сразу. Первая — архитектура приложения на примере NestJS: модули, провайдеры, контейнер внедрения зависимостей. Вторая — жизненный цикл запроса: как запрос проходит через middleware, guards, pipes, interceptors и filters, и почему этот порядок — контракт, а не произвол. Третья — дизайн API как контракта: REST в деталях, OpenAPI-документация, realtime-протоколы (WebSocket и SSE), GraphQL и gRPC — подходы к задаче «отдать данные клиенту» с разными компромиссами. Четвёртая — асинхронность между сервисами: очереди сообщений и outbox-паттерн для работы, которая происходит после ответа клиенту.
Зачем именно NestJS
Заголовок раздела «Зачем именно NestJS»Express — это фантастический HTTP-движок и ужасный каркас приложения. Он не говорит тебе, где лежит бизнес-логика, как разделить проект на части и как сделать так, чтобы двадцать сервисов не превратились в двадцать уникальных способов делать одно и то же. NestJS берёт проверенную серверную практику — модули, DI, декораторы, единый пайплайн запроса — и переносит её в мир TypeScript (см. официальную документацию). Под капотом тот же Express (или Fastify), вся магия из урока про Event Loop работает без изменений, но сверху появляется архитектура.
Порядок глав
Заголовок раздела «Порядок глав»- NestJS: модули, провайдеры, DI — фундамент фреймворка. Разбираем, как устроен DI-контейнер: рефлексия метаданных, декораторы,
emitDecoratorMetadata. Учимся регистрировать провайдеры черезuseClass/useFactory/useValue, управлять scope’ами (DEFAULT / REQUEST / TRANSIENT) и разруливать циклические зависимости черезforwardRef. Это глава, без которой остальные не имеют смысла. - Жизненный цикл запроса — middleware → guards → interceptors → pipes → handler → interceptors → filters. Строим ролевую модель на metadata и
Reflector, валидируем DTO черезclass-validator, пишем interceptor для логирования и единый exception filter. Поймёшь, почему порядок этапов — это не эстетика, а производительность и безопасность. - REST-дизайн и OpenAPI — ресурсное моделирование, вложенные ресурсы, идемпотентность методов, разбор статус-кодов, версионирование, пагинация offset vs cursor, фильтрация и сортировка, идемпотентные ключи. Заканчиваем автогенерацией OpenAPI-схемы из декораторов и красивой документацией на Scalar.
- Realtime API: WebSocket и SSE — чем realtime отличается от request/response: WebSocket handshake и фреймы под капотом, NestJS Gateway с комнатами, авторизация JWT в handshake, SSE для односторонних событий, reconnect с backoff, backpressure и heartbeat, масштабирование через Redis Pub/Sub adapter и проксирование через Nginx.
- GraphQL, DataLoader, gRPC — два альтернативных протокола. GraphQL: схема, резолверы, подписки, проклятие N+1 и его лечение через DataLoader. gRPC: Protocol Buffers, четыре вида RPC, генерация кода, транспорт микросервисов в NestJS. В конце — честное сравнение REST / GraphQL / gRPC и критерии выбора.
- Очереди и outbox на практике — асинхронность между сервисами: проблема двойной записи, outbox pattern в PostgreSQL, RabbitMQ (exchange, binding, routing key), retry через TTL/DLX, DLQ, идемпотентный consumer, упорядоченность и честное сравнение брокеров.
Как этот раздел связан с остальным учебником
Заголовок раздела «Как этот раздел связан с остальным учебником»NestJS стоит на плечах Node.js из прошлого раздела: каждый guard, pipe и interceptor — обычная асинхронная функция в том самом Event Loop. Realtime и очереди опираются на Redis (Pub/Sub adapter, Streams) и PostgreSQL (outbox-таблица в той же транзакции, что и бизнес-данные). Дальше раздел опирается на PostgreSQL и Redis: сервисы, которые ты пишешь здесь, будут доставать данные из БД, а guards — проверять JWT, которые разберём в главе про аутентификацию. Наконец, спроектированный здесь API ты потом упакуешь в Docker-образ и выкатишь через CI/CD — этапы 10–11.
Всё, карта есть. Начинаем с фундамента — модулей и контейнера зависимостей.