Первый сервер на Express: короткое руководство для старта
За 20 минут вы поднимете HTTP-сервер на Node.js и Express, отдадите JSON, обработаете POST-запрос и разберётесь, что делать, когда порт занят или модуль не находится.

К концу этого руководства у вас будет работающий HTTP-сервер на Express 4.x, который отвечает на запросы в браузере, отдаёт JSON и принимает данные через POST. Займёт это 15–20 минут, если Node.js уже установлен. Всё, что нужно, — терминал, редактор кода и один установленный пакет.
Что нужно иметь до начала
Проверьте, что окружение готово. Express — это библиотека для Node.js, отдельного рантайма она не требует, но сам Node.js обязателен.
- Node.js 18 или новее. Проверьте командой
node -v— должна вывестись версия вродеv20.11.0. Если команда не найдена, установите Node.js с официального сайта. - npm — ставится вместе с Node.js. Проверка:
npm -v. - Пустая папка под проект и права на запись в неё. На своём компьютере с этим проблем нет; если работаете на общем сервере — убедитесь, что можете создавать файлы.
Express 4.x — стабильная ветка, на которой написано большинство примеров в сети. Есть уже и Express 5.x, там часть поведения изменилась (например, обработка асинхронных ошибок), но для первого сервера ставим 4.x, чтобы код совпадал с большинством руководств.
Пошаговая настройка
-
Создайте папку проекта и войдите в неё.
mkdir my-first-server cd my-first-serverПроверка: команда
pwd(илиcdбез аргументов в Windows) покажет, что вы внутриmy-first-server. -
Инициализируйте проект. Флаг
-yсогласится со всеми вопросами по умолчанию.npm init -yПроверка: в папке появится файл
package.json. Откройте его — там должно быть поле"name": "my-first-server". -
Установите Express.
npm install expressПроверка: появится папка
node_modulesи файлpackage-lock.json, а вpackage.jsonв разделеdependenciesдобавится строка вида"express": "^4.19.2"(версия может отличаться). -
Создайте файл
server.jsв корне проекта и вставьте код целиком:// server.js — минимальный сервер на Express 4.x const express = require('express'); const app = express(); const PORT = 3000; // маршрут для корня: отвечает текстом app.get('/', (req, res) => { res.send('Сервер работает'); }); // запускаем прослушивание порта app.listen(PORT, () => { console.log(`Сервер запущен: http://localhost:${PORT}`); }); -
Запустите сервер.
node server.jsПроверка: в терминале появится строка
Сервер запущен: http://localhost:3000. Терминал «зависнет» — это нормально, процесс работает и ждёт запросы. Остановить его можно сочетаниемCtrl + C. -
Откройте браузер и перейдите по адресу
http://localhost:3000.Проверка: на странице появится текст
Сервер работает. Если видите его — HTTP-сервер поднят.
Отдаём JSON
Строка в браузере — это разминка. Реальные серверы чаще отдают данные в формате JSON, который потом читает фронтенд или мобильное приложение. Добавьте новый маршрут перед вызовом app.listen:
// возвращаем объект в формате JSON
app.get('/api/user', (req, res) => {
res.json({
id: 1,
name: 'Иван',
active: true,
});
});
Остановите сервер (Ctrl + C) и запустите заново: node server.js. Node.js не перечитывает файл на лету — после каждого изменения кода перезапуск обязателен. Откройте http://localhost:3000/api/user — браузер покажет объект {"id":1,"name":"Иван","active":true}. Метод res.json() сам проставит заголовок Content-Type: application/json.
Каждое изменение в server.js требует перезапуска процесса. Если правка не видна — почти всегда причина в том, что вы забыли остановить старый процесс и запустить новый.
Принимаем POST-запрос
Чтобы сервер мог читать данные, которые ему присылают в теле запроса, нужно включить встроенный разборщик JSON. В Express 4.16 и новее он входит в состав пакета — отдельная библиотека body-parser больше не нужна.
// подключаем разбор JSON в теле запроса — ставим до маршрутов
app.use(express.json());
// принимаем данные и возвращаем их обратно
app.post('/api/echo', (req, res) => {
const data = req.body;
res.json({ received: data });
});
Строка app.use(express.json()) должна идти до объявления POST-маршрута, иначе req.body будет undefined. Проверить POST через адресную строку браузера нельзя — она делает только GET. Используйте curl:
curl -X POST http://localhost:3000/api/echo \
-H "Content-Type: application/json" \
-d '{"message":"привет"}'
В ответ придёт {"received":{"message":"привет"}}. Если тело пустое — проверьте, что передали заголовок Content-Type: application/json и что express.json() подключён.
Как читать маршруты
Три вещи определяют, какой код сработает на запрос.
| Элемент | Что задаёт | Пример |
|---|---|---|
| HTTP-метод | Тип действия: чтение, создание | app.get, app.post |
| Путь | Адрес после домена и порта | /, /api/user |
| Обработчик | Функция (req, res), что вернуть | res.send, res.json |
Объект req — это входящий запрос (что прислали), res — исходящий ответ (что вернуть). Отправить ответ нужно ровно один раз: вызов res.send или res.json завершает обработку. Два вызова подряд дадут ошибку ERR_HTTP_HEADERS_SENT.
Если не получилось
Error: Cannot find module 'express'— пакет не установлен или вы запускаете сервер не из той папки. Убедитесь, что рядом сserver.jsлежит папкаnode_modules, и повторитеnpm install express.Error: listen EADDRINUSE: address already in use :::3000— порт 3000 уже занят другим процессом (часто это старый экземпляр этого же сервера, который вы забыли закрыть). Закройте его или поменяйтеconst PORT = 3000на3001.- Браузер показывает
Cannot GET /api/user— такого маршрута нет. Проверьте, что путь в коде совпадает с адресом до буквы, и что вы перезапустили сервер после добавления маршрута. req.bodyравенundefined— не подключёнexpress.json()или он объявлен после маршрута. Перенеситеapp.use(express.json())выше.SyntaxError: Unexpected tokenпри старте — опечатка вserver.js, чаще всего незакрытая скобка или кавычка. Node.js укажет номер строки — смотрите её и соседние.
Что делать дальше
Сервер работает — теперь стоит убрать ручные перезапуски. Установите nodemon командой npm install --save-dev nodemon и запускайте сервер через npx nodemon server.js — он сам перечитает файл при каждом сохранении. Дальше по порядку: вынесите маршруты в отдельные файлы через express.Router(), добавьте единый обработчик ошибок и перестаньте хранить порт в коде — читайте его из переменной окружения process.env.PORT, чтобы приложение можно было развернуть на хостинге без правки исходников.
Инфографика для маркетплейса: Три главных преимущества товара короткими фразами, выноски в безопасной зоне превью, точный размер площадки.
Спросить за 60 ₽Источники: Express — официальная документация, раздел «Getting started», Express 4.x API Reference
Частые вопросы
У меня Express 5.x, а не 4.x — код из руководства сработает?
Нужен ли отдельный пакет body-parser для чтения POST?
Почему изменения в коде не видны в браузере?
Порт 3000 занят — что делать?
Можно ли открыть этот сервер из интернета, а не только на localhost?
Чем res.send отличается от res.json?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.