Створення надійного бекенду вимагає добре структурованої архітектури, яка організує ваш код і спрощує його підтримку. Одним із найпопулярніших патернів для структуризації бекенд-застосунків є архітектура Model-View-Controller (MVC). Цей блог ознайомить вас з MVC, обговорить типи логіки та покаже, як рефакторити простий застосунок на Express у структуру MVC.
Вступ до архітектури бекенду: MVC
Що таке MVC?
MVC — це скорочення від Model-View-Controller, патерн проектування, який розділяє логіку застосунку на три взаємопов'язані компоненти:
- Модель (Model): Керує даними, логікою та правилами застосунку. Вона безпосередньо взаємодіє з базою даних.
- Подання (View): Обробляє презентаційний рівень — те, що бачить користувач (HTML, JSON відповіді тощо).
- Контролер (Controller): Діє як посередник між Моделлю та Поданням. Він обробляє введення користувача, взаємодіє з Моделлю і визначає, що повинно відображатися в Поданні.
Чому використовувати MVC?
- Розподіл відповідальності (Separation of Concerns): Кожен рівень обробляє конкретний аспект, що робить код простішим для розуміння і підтримки.
- Масштабованість: Модульний дизайн спрощує додавання нових функцій.
- Повторне використання (Reusability): Компоненти можуть бути повторно використані в різних частинах застосунку.
Типи логіки в розробці бекенду
При створенні бекенд-застосунків логіка зазвичай ділиться на три типи:
- Бізнес-логіка (Business Logic): Визначає, як дані можуть бути створені, збережені або змінені. Наприклад, перевірка віку користувача перед створенням профілю.
- Презентаційна логіка (Presentation Logic): Обробляє форматування і відображення даних користувачеві.
- Логіка маршрутизації (Routing Logic): Направляє вхідні запити до правильного контролера або функції.
Розуміння цих типів допомагає визначити, куди має потрапляти кожен функціональний блок в структурі MVC.
Рефакторинг до MVC
Щоб продемонструвати рефакторинг до MVC, почнемо з простого застосунку на Express, який не має структури, і організуємо його в патерн MVC.
Початковий код: Простий застосунок на Express
Ось базовий застосунок на Express:
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/myApp', {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log('Database connected')).catch(err => console.error(err));
const tourSchema = new mongoose.Schema({
name: String,
price: Number,
});
const Tour = mongoose.model('Tour', tourSchema);
app.get('/tours', async (req, res) => {
const tours = await Tour.find();
res.status(200).json(tours);
});
app.post('/tours', async (req, res) => {
const newTour = await Tour.create(req.body);
res.status(201).json(newTour);
});
app.listen(3000, () => console.log('Server running on port 3000'));
Цей застосунок працює, але змішує маршрутизацію, бізнес-логіку та операції з базою даних в одному файлі.
Давайте рефакторимо це, використовуючи MVC.
Крок 1: Організуйте файли
Створіть нову структуру для вашого застосунку:
project-folder/
|-- models/
| |-- tourModel.js
|-- controllers/
| |-- tourController.js
|-- routes/
| |-- tourRoutes.js
|-- app.js
|-- server.js
Крок 2: Створіть Модель
Перемістіть схему та модель в models/tourModel.js
:
const mongoose = require('mongoose');
const tourSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'A tour must have a name'],
},
price: {
type: Number,
required: [true, 'A tour must have a price'],
},
});
const Tour = mongoose.model('Tour', tourSchema);
module.exports = Tour;
Крок 3: Створіть Контролер
Перемістіть логіку маршруту в controllers/tourController.js
:
const Tour = require('../models/tourModel');
exports.getAllTours = async (req, res) => {
try {
const tours = await Tour.find();
res.status(200).json({
status: 'success',
results: tours.length,
data: { tours },
});
} catch (err) {
res.status(500).json({
status: 'error',
message: err.message,
});
}
};
exports.createTour = async (req, res) => {
try {
const newTour = await Tour.create(req.body);
res.status(201).json({
status: 'success',
data: { tour: newTour },
});
} catch (err) {
res.status(400).json({
status: 'fail',
message: err.message,
});
}
};
Крок 4: Налаштуйте Маршрути
Оголосіть маршрути в routes/tourRoutes.js
:
const express = require('express');
const tourController = require('../controllers/tourController');
const router = express.Router();
router.route('/')
.get(tourController.getAllTours)
.post(tourController.createTour);
module.exports = router;
Крок 5: Оновіть файл App
Використовуйте маршрути в app.js
:
const express = require('express');
const tourRoutes = require('./routes/tourRoutes');
const app = express();
app.use(express.json());
app.use('/api/v1/tours', tourRoutes);
module.exports = app;
Крок 6: Запустіть сервер
Перемістіть логіку запуску сервера в server.js
:
const app = require('./app');
const PORT = 3000;
app.listen(PORT, () => {
console.log(`App running on port ${PORT}`);
});
Висновок
Після рефакторингу застосунку на Express у патерн MVC ми розділили відповідальність і покращили підтримуваність. Модель обробляє дані, контролер управляє логікою, а маршрути з'єднують усе разом. Така структура добре масштабується і підтримує чистоту вашого коду, особливо коли ваш застосунок росте. Удачі в програмуванні!
Перекладено з: Understanding Back-End Architecture: MVC and Refactoring for Clean Code