Опенсорс-фреймворк
noServer
Node.js веб-фреймворк без единой зависимости, построенный с нуля на «голых» TCP-сокетах — собственный парсер HTTP/1.1 и реализация WebSocket с конфигурируемой маршрутизацией, CRUD, CORS, ограничением частоты и раздачей статики. Изучение того, как на самом деле работают веб-серверы, с первых принципов.
Обзор
Я создал noServer, чтобы понять, что на самом деле происходит, когда веб-сервер обрабатывает запрос — не через абстракцию фреймворка, а на уровне сырого сокета. Ноль зависимостей: никаких npm-пакетов, никакого модуля http. Реализует парсинг HTTP/1.1, гибридный роутер, WebSocket, ограничение частоты, генерацию CRUD и раздачу статических файлов — всё в одном файле, с первых принципов.
Что я сделал
Единственный автор — построил каждый слой с нуля: обработка TCP-сокетов, парсинг HTTP, движок маршрутизации, протокол WebSocket и конфигурационный API для разработчиков.
Протестировал три разные стратегии маршрутизации для обоснования финального дизайна — результаты бенчмарка зафиксированы вместе с кодом, чтобы решение всегда было отслеживаемым.
Написал raw-TCP тестовый клиент, вручную создающий HTTP/1.1 строки запросов для проверки поведения сервера сквозным образом — никакой тестовой библиотеки, только сырые сокеты.
Архитектура
Сервер открывает сырой TCP-сокет и буферизирует входящие данные до прихода полного HTTP-запроса — определяемого пустой строкой после заголовков плюс Content-Length для тела. Маршруты хранятся в двух структурах: хеш-карта простых объектов для статических путей (поиск за константное время) и единый скомпилированный regex для параметризованных путей, так что один вызов match захватывает маршрут и извлекает все параметры сразу. WebSocket-апгрейд переключает сокет из текстового в режим бинарных фреймов на оставшееся время жизни.
Под капотом
WebSocket реализован вручную по RFC-спецификации — хендшейк, декодирование фреймов и кодирование фреймов, включая все три кодировки длины полезной нагрузки и XOR-демаскирование. Ping автоматически отвечает Pong. Ничего из npm не заимствовано.
Гибридный роутер проверен против двух альтернатив: статические пути используют хеш-карту для поиска за константное время, динамические пути используют единый скомпилированный regex, где смещение группы захвата каждого маршрута предварительно вычислено — так что один вызов match выполняет и маршрутизацию, и извлечение параметров. Бенчмарк подтвердил превосходство над линейным сканированием и подходом в стиле Hono на 500k итерациях.
Защита полноты тела HTTP: сервер буферизирует входящие данные и только диспетчеризирует запрос после получения всех байт, обещанных Content-Length — предотвращая баги неполной обработки тела, которые печально известны сложностью воспроизведения.
Чему я научился
Реализация HTTP с нуля дала мне чёткое представление о том, что скрывают фреймворки — и заставила оценить, почему они существуют. Граница между «образовательным» и «готовым к продакшену» реальна.
Бенчмаркинг алгоритмов маршрутизации перед окончательным выбором сэкономил время впоследствии — наличие чисел в репозитории означает, что мне никогда не приходилось заново аргументировать решение.
Технологии
Среда выполнения
- Node.js
- net (TCP)
- crypto
- fs
- path
Построено с нуля (нет зависимостей)
- HTTP/1.1 parser
- RFC 6455 WebSocket
- Hybrid router
- Rate limiter
- Auto-CRUD store
- ETag caching
- Static file server
Инструменты
- node --watch
- bench.js (router benchmark)
- test.js (raw-TCP test client)
