Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Express.js: назначение, архитектура и использование
Express.js — это минималистичный и мощный фреймворк для Node.js, который упрощает создание серверных приложений, REST API и веб-приложений. Это один из самых популярных фреймворков в Node.js экосистеме.
Что такое Express
Express предоставляет удобный набор инструментов для:
- Обработки HTTP запросов
- Маршрутизации (routing)
- Управления middleware
- Обработки ошибок
- Сервирования статичных файлов
// Без Express (нативный Node.js)
const http = require('http');
const server = http.createServer((req, res) => {
// Всё нужно писать вручную: парсинг URL, методов и т.д.
if (req.method === 'GET' && req.url === '/users') {
const users = [{ id: 1, name: 'Alice' }];
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(users));
} else if (req.method === 'POST' && req.url === '/users') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const user = JSON.parse(body);
// Сохранить пользователя
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(user));
});
} else {
res.writeHead(404);
res.end('Not Found');
}
});
server.listen(3000);
// Много boilerplate кода, сложно масштабировать
// С Express (значительно проще)
const express = require('express');
const app = express();
app.use(express.json()); // Парсинг JSON автоматически
app.get('/users', (req, res) => {
const users = [{ id: 1, name: 'Alice' }];
res.json(users); // JSON парсинг встроен
});
app.post('/users', (req, res) => {
const user = req.body; // Автоматически распарсен
// Сохранить пользователя
res.status(201).json(user);
});
app.listen(3000);
// Чистый, понятный код
Основные возможности Express
1. Маршрутизация (Routing)
const express = require('express');
const app = express();
// GET запросы
app.get('/users', (req, res) => {
res.json({ message: 'Get all users' });
});
app.get('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `Get user ${id}` });
});
// POST запросы
app.post('/users', (req, res) => {
const { name, email } = req.body;
res.status(201).json({ id: 1, name, email });
});
// PUT запросы
app.put('/users/:id', (req, res) => {
const { id } = req.params;
const { name, email } = req.body;
res.json({ id, name, email });
});
// DELETE запросы
app.delete('/users/:id', (req, res) => {
const { id } = req.params;
res.json({ message: `User ${id} deleted` });
});
// Query параметры
app.get('/search', (req, res) => {
const { q, limit } = req.query; // ?q=test&limit=10
res.json({ query: q, limit });
});
2. Middleware (обработчики)
Middleware — это функция, которая обрабатывает запрос перед отправкой ответа:
// Логирование
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next(); // Передать управление следующему middleware
});
// Парсинг JSON
app.use(express.json());
// Парсинг URL encoded
app.use(express.urlencoded({ extended: true }));
// Сервирование статичных файлов
app.use(express.static('public'));
// Проверка авторизации
app.use('/admin', (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
});
// Middleware может быть на конкретном маршруте
const authenticate = (req, res, next) => {
// Проверить токен
next();
};
app.post('/posts', authenticate, (req, res) => {
// Только авторизованные пользователи могут создавать посты
res.json({ message: 'Post created' });
});
// Цепочка middleware
app.put('/users/:id',
authenticate,
validateUserData,
updateUser
);
3. Обработка ошибок
// Error handling middleware (4 параметра!)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong' });
});
// Должен быть в конце app.use
// Пример использования
app.get('/users/:id', async (req, res, next) => {
try {
const user = await getUserFromDB(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
} catch (error) {
next(error); // Передать ошибку в error handler
}
});
4. Router (для большых приложений)
// users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
});
router.post('/', (req, res) => {
const user = req.body;
res.status(201).json(user);
});
router.get('/:id', (req, res) => {
res.json({ id: req.params.id, name: 'User' });
});
router.put('/:id', (req, res) => {
res.json({ ...req.body, id: req.params.id });
});
router.delete('/:id', (req, res) => {
res.json({ message: 'Deleted' });
});
module.exports = router;
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const postsRouter = require('./routes/posts');
const app = express();
app.use(express.json());
app.use('/api/v1/users', usersRouter);
app.use('/api/v1/posts', postsRouter);
app.listen(3000);
Архитектурный паттерн: MVC
Express часто используется с MVC (Model-View-Controller) паттерном:
// routes/users.js
const express = require('express');
const usersController = require('../controllers/users');
const router = express.Router();
router.get('/', usersController.getAll);
router.get('/:id', usersController.getById);
router.post('/', usersController.create);
router.put('/:id', usersController.update);
router.delete('/:id', usersController.delete);
module.exports = router;
// controllers/users.js
const User = require('../models/User');
const getAll = async (req, res, next) => {
try {
const users = await User.findAll();
res.json(users);
} catch (error) {
next(error);
}
};
const getById = async (req, res, next) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'Not found' });
}
res.json(user);
} catch (error) {
next(error);
}
};
const create = async (req, res, next) => {
try {
const user = await User.create(req.body);
res.status(201).json(user);
} catch (error) {
next(error);
}
};
// ... update, delete
module.exports = { getAll, getById, create };
// models/User.js
const db = require('../db');
class User {
static async findAll() {
const [users] = await db.query('SELECT * FROM users');
return users;
}
static async findById(id) {
const [users] = await db.query('SELECT * FROM users WHERE id = ?', [id]);
return users[0];
}
static async create(data) {
const { name, email } = data;
const [result] = await db.query(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
return { id: result.insertId, name, email };
}
// ... update, delete
}
module.exports = User;
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const app = express();
app.use(express.json());
app.use('/api/v1/users', usersRouter);
app.listen(3000);
Зачем Express нужен Frontend разработчику
1. Локальная разработка (Dev server)
// server.js
const express = require('express');
const path = require('path');
const app = express();
// Сервировать React приложение
app.use(express.static(path.join(__dirname, 'build')));
// API mock
app.get('/api/v1/users', (req, res) => {
res.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
});
// SPA fallback (для React Router)
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(3000);
2. Mock API для тестирования
// Во время разработки фронта часто бэк не готов
// Express помогает создать mock API
app.get('/api/v1/posts', (req, res) => {
res.json([
{ id: 1, title: 'Post 1', content: 'Content 1' },
{ id: 2, title: 'Post 2', content: 'Content 2' }
]);
});
app.post('/api/v1/posts', (req, res) => {
const { title, content } = req.body;
res.status(201).json({
id: 3,
title,
content,
createdAt: new Date()
});
});
3. BFF (Backend For Frontend)
Иногда фронт-разработчик пишет небольшой сервер для агрегации API:
// вместо 3 запросов на фронте, делаем 1 на BFF
app.get('/api/v1/dashboard', async (req, res) => {
try {
const users = await fetch('https://api.internal.com/users');
const posts = await fetch('https://api.internal.com/posts');
const comments = await fetch('https://api.internal.com/comments');
res.json({
users: await users.json(),
posts: await posts.json(),
comments: await comments.json()
});
} catch (error) {
res.status(500).json({ error: 'Failed' });
}
});
Популярные middleware и расширения
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const app = express();
// CORS
app.use(cors({
origin: 'https://example.com',
credentials: true
}));
// Security headers
app.use(helmet());
// HTTP logging
app.use(morgan('combined'));
// Compression (gzip)
app.use(compression());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
});
app.use('/api/', limiter);
// Body parsing
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));
Альтернативы Express
// Fastify (быстрее, современнее)
const fastify = require('fastify')();
fastify.get('/users', async () => {
return { users: [] };
});
await fastify.listen({ port: 3000 });
// Koa (меньше middleware в коробке, более гибкий)
const Koa = require('koa');
const app = new Koa();
app.use(ctx => {
ctx.body = { message: 'Hello' };
});
app.listen(3000);
// Next.js (для React приложений с SSR)
// Встроенный Express внутри, проще использовать
Простой пример полного приложения
const express = require('express');
const app = express();
app.use(express.json());
app.use(morgan('dev'));
app.use(cors());
// Routes
app.get('/api/v1/users', (req, res) => {
res.json([{ id: 1, name: 'Alice' }]);
});
app.post('/api/v1/users', (req, res) => {
const { name } = req.body;
res.status(201).json({ id: 2, name });
});
// Error handling
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Internal error' });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Итог
Express нужен для:
- Быстрого создания REST API
- Простой маршрутизации
- Middleware (логирование, авторизация, валидация)
- Обработки ошибок
- Сервирования статичных файлов
Для фронт-разработчиков:
- Mock API во время разработки
- BFF (Backend For Frontend)
- Локальная разработка с реалистичным сервером
- Простая альтернатива созданию полноценного backend
Плюсы:
- Минималистичный (не навязывает структуру)
- Огромная экосистема middleware
- Очень популярен (много примеров и help)
- Легко выучить и использовать
Express — де-факто стандартный выбор для Node.js приложений в 2024 году.