Skip to main content
Практика завдань

Як структурувати велику програму на Express.js?

Структурування великого додатку на Express.js

Коли додатки на Express зростають, плоска структура стає незручна для обслуговування. Добре структурований додаток розділяє обов'язки, що робить його тестованим, масштабованим і легким для навігації.


Рекомендована структура папок

src/ ├── app.js ← Налаштування додатку Express (без listen()) ├── server.js ← Точка входу (запускає сервер) ├── config/ │ ├── index.js ← Налаштування додатку (PORT, DB_URL тощо) │ └── database.js ← Підключення до БД ├── routes/ │ ├── index.js ← Кореневий маршрутизатор (монтує всі маршрутизатори) │ ├── users.routes.js │ └── products.routes.js ├── controllers/ │ ├── users.controller.js │ └── products.controller.js ├── services/ │ ├── users.service.js ← Бізнес-логіка │ └── email.service.js ├── models/ │ ├── User.model.js │ └── Product.model.js ├── middleware/ │ ├── auth.middleware.js │ ├── validate.middleware.js │ └── rateLimiter.middleware.js ├── validators/ │ ├── users.validator.js │ └── products.validator.js └── utils/ ├── AppError.js ├── asyncHandler.js └── logger.js

app.js — Чисте налаштування Express

js
// src/app.js const express = require('express'); const helmet = require('helmet'); const cors = require('cors'); const { corsOptions } = require('./config'); const routes = require('./routes'); const { notFound, errorHandler } = require('./middleware/error.middleware'); const app = express(); // Безпека та парсинг app.use(helmet()); app.use(cors(corsOptions)); app.use(express.json({ limit: '10kb' })); // Маршрути app.use('/api/v1', routes); // Обробка помилок (завжди остання) app.use(notFound); app.use(errorHandler); module.exports = app;

server.js — Точка входу

js
// src/server.js const app = require('./app'); const { connectDB } = require('./config/database'); const PORT = process.env.PORT || 3000; async function start() { await connectDB(); app.listen(PORT, () => { console.log(`Сервер працює на порту ${PORT}`); }); } start().catch(console.error);

Шар маршрутизації

js
// src/routes/index.js const router = require('express').Router(); const usersRoutes = require('./users.routes'); const productsRoutes = require('./products.routes'); router.use('/users', usersRoutes); router.use('/products', productsRoutes); module.exports = router; // src/routes/users.routes.js const router = require('express').Router(); const { getUsers, getUser, createUser } = require('../controllers/users.controller'); const { authenticate } = require('../middleware/auth.middleware'); const { validateCreateUser } = require('../validators/users.validator'); router.get('/', authenticate, getUsers); router.get('/:id', authenticate, getUser); router.post('/', validateCreateUser, createUser); module.exports = router;

Шар контролерів

js
// src/controllers/users.controller.js const asyncHandler = require('../utils/asyncHandler'); const usersService = require('../services/users.service'); const AppError = require('../utils/AppError'); exports.getUsers = asyncHandler(async (req, res) => { const users = await usersService.findAll(req.query); res.json({ success: true, data: users }); }); exports.getUser = asyncHandler(async (req, res) => { const user = await usersService.findById(req.params.id); if (!user) throw new AppError('Користувача не знайдено', 404); res.json({ success: true, data: user }); });

Шар сервісів (Бізнес-логіка)

js
// src/services/users.service.js const User = require('../models/User.model'); exports.findAll = async ({ page = 1, limit = 10 }) => { const skip = (page - 1) * limit; return User.find().skip(skip).limit(Number(limit)); }; exports.findById = async (id) => { return User.findById(id); }; exports.create = async (data) => { return User.create(data); };

Підсумок шарів

ШарВідповідальність
МаршрутиВизначення відповідності URL → обробник, застосування проміжного програмного забезпечення
КонтролериОбробка req/res, виклик сервісів, відправка відповіді
СервісиБізнес-логіка, доступ до бази даних
МоделіСхема даних та інтерфейс бази даних
Проміжне програмне забезпеченняПерехресні функції: аутентифікація, логування, валідація
КонфігураціяЗмінні середовища, константи

Підсумок

Розділіть ваш додаток на маршрути → контролери → сервіси → моделі. Залиште Express app у app.js (без listen()) і запускайте його у server.js. Це робить додаток тестованим (імпортуйте app.js у тестах без запуску сервера) і кожен шар незалежно обслуговуваним.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань