Антон Ларичев

Введение
REST API — это архитектурный стиль взаимодействия клиента и сервера через HTTP-протокол. Node.js в связке с Express позволяет быстро построить такой API: минимум кода, гибкая маршрутизация и богатая экосистема middleware. В этой статье разберём, как с нуля создать рабочий REST API для управления списком пользователей: настроим проект, реализуем CRUD-операции, подключим валидацию и научимся обрабатывать ошибки.
Подготовка проекта
Создадим директорию и инициализируем npm-проект:
mkdir users-api && cd users-api
npm init -y
npm install express
npm install -D nodemon
В package.json добавим скрипт для запуска в режиме разработки:
{
"scripts": {
"dev": "nodemon index.js",
"start": "node index.js"
}
}
nodemon автоматически перезапускает сервер при изменении файлов — это экономит время на разработку.
Базовый сервер Express
Создадим файл index.js с минимальным сервером:
const express = require('express');
const app = express();
const PORT = 3000;
// Подключаем парсер JSON для тела запросов
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'API работает' });
});
app.listen(PORT, () => {
console.log(`Сервер запущен на порту ${PORT}`);
});
Запускаем командой npm run dev и проверяем http://localhost:3000 — должны увидеть JSON-ответ. express.json() — встроенный middleware, который парсит тело запроса в формате JSON и кладёт результат в req.body.
Реализация CRUD-операций
REST подразумевает использование HTTP-методов для разных действий: GET — получение, POST — создание, PUT — обновление, DELETE — удаление. Реализуем ресурс users с временным хранилищем в памяти.
// Временное хранилище данных
let users = [
{ id: 1, name: 'Анна', email: 'anna@mail.ru' },
{ id: 2, name: 'Иван', email: 'ivan@mail.ru' }
];
let nextId = 3;
// Получение списка пользователей
app.get('/users', (req, res) => {
res.json(users);
});
// Получение одного пользователя
app.get('/users/:id', (req, res) => {
const id = Number(req.params.id);
const user = users.find(u => u.id === id);
if (!user) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
res.json(user);
});
// Создание нового пользователя
app.post('/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'name и email обязательны' });
}
const user = { id: nextId++, name, email };
users.push(user);
res.status(201).json(user);
});
// Обновление пользователя
app.put('/users/:id', (req, res) => {
const id = Number(req.params.id);
const user = users.find(u => u.id === id);
if (!user) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
Object.assign(user, req.body);
res.json(user);
});
// Удаление пользователя
app.delete('/users/:id', (req, res) => {
const id = Number(req.params.id);
users = users.filter(u => u.id !== id);
res.status(204).send();
});
Обратите внимание на коды состояния: 200 — успех, 201 — создан ресурс, 204 — успех без тела ответа, 400 — ошибка клиента, 404 — не найдено. Корректное использование статусов — обязательная часть REST.
Middleware и обработка ошибок
Middleware — это функция, которая выполняется между запросом и ответом. С её помощью удобно реализовать логирование, авторизацию и централизованную обработку ошибок.
// Логирование всех запросов
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// Глобальный обработчик ошибок
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Внутренняя ошибка сервера' });
});
Обработчик ошибок должен иметь четыре аргумента — Express определяет его по сигнатуре. Размещать его нужно после всех маршрутов.
Вынесение маршрутов в роутер
Когда эндпоинтов становится много, полезно разделить код на модули с помощью express.Router:
// routes/users.js
const router = require('express').Router();
router.get('/', (req, res) => res.json(users));
router.post('/', (req, res) => { /* логика */ });
module.exports = router;
// index.js
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);
Такая структура упрощает поддержку и масштабирование проекта.
Частые ошибки
Забытый express.json(). Без этого middleware req.body будет undefined, и POST-запросы перестанут работать. Подключайте его в самом начале до объявления маршрутов.
Отсутствие валидации входных данных. Доверять данным клиента нельзя — используйте библиотеки joi, zod или express-validator для проверки типов и обязательных полей.
Игнорирование асинхронных ошибок. Если внутри обработчика возникает ошибка в async-функции, Express её не поймает автоматически. Оборачивайте логику в try/catch или используйте express-async-errors.
Неправильные HTTP-статусы. Возвращать 200 для ошибок — антипаттерн. Клиент должен по статусу понимать, что произошло.
Хранение данных в памяти. Это допустимо только для прототипа. В реальном приложении нужна БД: PostgreSQL, MongoDB или хотя бы SQLite.
Заключение
Мы построили рабочий REST API на Node.js и Express: настроили проект, реализовали CRUD-операции, добавили middleware для логирования и обработки ошибок, вынесли маршруты в отдельный модуль. Следующие шаги — подключение базы данных через ORM (Prisma, TypeORM), добавление аутентификации через JWT, написание тестов с помощью Jest и Supertest, а также деплой на сервер. Express остаётся одним из самых популярных фреймворков для бэкенда на Node.js именно благодаря простоте и гибкости, которую вы только что увидели на практике.






Комментарии
0