- Home »

Основы Node.js Express — начало работы
Если вы админите серверы или разрабатываете веб-приложения, то наверняка слышали о Node.js Express — одном из самых популярных фреймворков для создания серверных приложений на JavaScript. Эта статья поможет вам разобраться с основами Express, понять его архитектуру и научиться создавать полноценные веб-приложения с нуля. Мы пройдем от установки до деплоя, разберем практические примеры и покажем, как избежать типичных ошибок новичков.
Что такое Express и зачем он нужен
Express.js — это минималистичный и гибкий фреймворк для Node.js, который предоставляет мощный набор функций для веб-приложений и API. По сути, это прослойка над базовым HTTP-модулем Node.js, которая делает разработку серверных приложений намного проще и быстрее.
Основные преимущества Express:
- Минимализм — фреймворк не навязывает структуру проекта
- Middleware — мощная система промежуточного ПО
- Роутинг — гибкая система маршрутизации
- Производительность — отличная скорость работы
- Экосистема — огромное количество готовых модулей
Установка и первоначальная настройка
Для начала работы с Express нужно установить Node.js (если еще не установлен) и создать новый проект:
# Создаем директорию проекта
mkdir my-express-app
cd my-express-app
# Инициализируем npm-проект
npm init -y
# Устанавливаем Express
npm install express
# Устанавливаем nodemon для автоматического перезапуска (dev-зависимость)
npm install --save-dev nodemon
Создаем файл app.js
с базовым сервером:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// Базовый роут
app.get('/', (req, res) => {
res.send('Hello World! Express работает!');
});
// Запуск сервера
app.listen(PORT, () => {
console.log(`Сервер запущен на порту ${PORT}`);
});
Добавляем в package.json
скрипты для удобства:
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}
Теперь можно запустить сервер командой npm run dev
и открыть в браузере http://localhost:3000
.
Основы роутинга
Роутинг в Express — это определение того, как приложение отвечает на различные запросы клиента. Базовая структура выглядит так:
app.METHOD(PATH, HANDLER)
Где:
METHOD
— HTTP-метод (GET, POST, PUT, DELETE и т.д.)PATH
— путь на сервереHANDLER
— функция-обработчик
Примеры различных типов роутов:
// GET-запрос
app.get('/users', (req, res) => {
res.json({ users: ['Alice', 'Bob', 'Charlie'] });
});
// POST-запрос
app.post('/users', (req, res) => {
res.status(201).json({ message: 'Пользователь создан' });
});
// Роут с параметрами
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.json({ userId: userId, name: 'John Doe' });
});
// Роут с query-параметрами
app.get('/search', (req, res) => {
const query = req.query.q;
res.json({ query: query, results: [] });
});
Middleware — сердце Express
Middleware — это функции, которые выполняются во время жизненного цикла запроса к серверу. Они имеют доступ к объектам запроса (req
), ответа (res
) и к следующей middleware-функции в цикле (next
).
Типы middleware:
- Application-level — привязаны к экземпляру приложения
- Router-level — привязаны к роутеру
- Error-handling — обрабатывают ошибки
- Built-in — встроенные в Express
- Third-party — сторонние модули
Примеры middleware:
// Встроенный middleware для парсинга JSON
app.use(express.json());
// Встроенный middleware для статических файлов
app.use(express.static('public'));
// Кастомный middleware для логирования
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next(); // Важно! Вызываем next() для перехода к следующему middleware
});
// Middleware для конкретного роута
app.get('/protected', authenticate, (req, res) => {
res.json({ message: 'Доступ разрешен' });
});
function authenticate(req, res, next) {
// Логика аутентификации
if (req.headers.authorization) {
next(); // Переходим к следующему обработчику
} else {
res.status(401).json({ error: 'Не авторизован' });
}
}
Обработка ошибок
Express имеет встроенную систему обработки ошибок. Error-handling middleware должен принимать четыре параметра:
// Middleware для обработки ошибок
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Что-то пошло не так!' });
});
// Пример роута с обработкой ошибок
app.get('/error-demo', (req, res, next) => {
try {
// Потенциально опасная операция
throw new Error('Демо ошибка');
} catch (error) {
next(error); // Передаем ошибку в error handler
}
});
Работа с базами данных
Express отлично работает с различными базами данных. Рассмотрим пример с MongoDB и Mongoose:
# Установка MongoDB драйвера
npm install mongoose
# Или для работы с PostgreSQL
npm install pg sequelize
const mongoose = require('mongoose');
// Подключение к MongoDB
mongoose.connect('mongodb://localhost:27017/myapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Схема пользователя
const userSchema = new mongoose.Schema({
name: String,
email: String,
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', userSchema);
// CRUD операции
app.get('/api/users', async (req, res) => {
try {
const users = await User.find();
res.json(users);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.post('/api/users', async (req, res) => {
try {
const user = new User(req.body);
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
Структура проекта и лучшие практики
Для больших проектов рекомендуется следующая структура:
my-express-app/
├── app.js # Точка входа
├── package.json
├── .env # Переменные окружения
├── routes/ # Роуты
│ ├── index.js
│ ├── users.js
│ └── api.js
├── middleware/ # Кастомные middleware
│ ├── auth.js
│ └── logger.js
├── models/ # Модели данных
│ └── User.js
├── controllers/ # Контроллеры
│ └── userController.js
├── config/ # Конфигурация
│ └── database.js
└── public/ # Статические файлы
├── css/
├── js/
└── images/
Пример разделения роутов:
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json({ message: 'Список пользователей' });
});
router.get('/:id', (req, res) => {
res.json({ message: `Пользователь ${req.params.id}` });
});
module.exports = router;
// app.js
const userRoutes = require('./routes/users');
app.use('/users', userRoutes);
Сравнение Express с альтернативами
Фреймворк | Производительность | Сложность | Экосистема | Подходит для |
---|---|---|---|---|
Express.js | Высокая | Низкая | Огромная | API, веб-приложения |
Fastify | Очень высокая | Средняя | Растущая | Высоконагруженные API |
Koa.js | Высокая | Средняя | Средняя | Современные приложения |
NestJS | Средняя | Высокая | Специализированная | Enterprise-приложения |
Деплой и продакшен
Для деплоя Express-приложения нужно подготовить его к продакшену:
# Установка PM2 для управления процессами
npm install -g pm2
# Запуск приложения с PM2
pm2 start app.js --name "my-express-app"
# Настройка автозапуска
pm2 startup
pm2 save
Пример конфигурации для PM2 (ecosystem.config.js
):
module.exports = {
apps: [{
name: 'my-express-app',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
}
}]
};
При выборе хостинга для Express-приложения рекомендую рассмотреть аренду VPS для небольших проектов или выделенный сервер для высоконагруженных приложений.
Безопасность Express-приложений
Основные меры безопасности:
# Установка пакетов безопасности
npm install helmet cors express-rate-limit
# Использование в приложении
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
// Базовая защита заголовков
app.use(helmet());
// CORS
app.use(cors({
origin: ['http://localhost:3000', 'https://mydomain.com'],
credentials: true
}));
// Ограничение количества запросов
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100 // максимум 100 запросов с одного IP
});
app.use(limiter);
Тестирование Express-приложений
Для тестирования Express-приложений можно использовать Jest и Supertest:
# Установка тестовых зависимостей
npm install --save-dev jest supertest
# Пример теста
const request = require('supertest');
const app = require('../app');
describe('GET /', () => {
test('should return 200 OK', async () => {
const response = await request(app).get('/');
expect(response.status).toBe(200);
});
});
Полезные пакеты для Express
- express-validator — валидация данных
- passport — аутентификация
- multer — загрузка файлов
- compression — сжатие ответов
- morgan — логирование HTTP-запросов
- dotenv — работа с переменными окружения
- jsonwebtoken — JWT токены
- bcryptjs — хэширование паролей
Распространенные ошибки и их решения
Ошибка: “Cannot set headers after they are sent”
Решение: Убедитесь, что не вызываете res.send()
или res.json()
несколько раз в одном роуте.
Ошибка: Middleware не выполняется
Решение: Проверьте порядок подключения middleware — они выполняются в том порядке, в котором подключены.
Ошибка: 404 для статических файлов
Решение: Убедитесь, что middleware для статических файлов подключен до роутов.
Заключение и рекомендации
Express.js остается одним из лучших выборов для создания серверных приложений на Node.js благодаря своей простоте, гибкости и огромной экосистеме. Он отлично подходит как для небольших API, так и для крупных веб-приложений.
Рекомендую использовать Express когда:
- Нужно быстро создать REST API
- Требуется максимальная гибкость в выборе архитектуры
- Важна производительность и минимальный оверхед
- Есть опыт работы с JavaScript/Node.js
Не рекомендую использовать Express если:
- Нужна строгая типизация (лучше выбрать NestJS с TypeScript)
- Требуется максимальная производительность (рассмотрите Fastify)
- Команда не знакома с Node.js экосистемой
Начинайте с простого — создайте базовое приложение, изучите middleware, добавьте базу данных и постепенно усложняйте функциональность. Express дает отличный фундамент для роста и развития ваших навыков в серверной разработке.
Полезные ссылки:
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.