Modularizzare un'applicazione Node.js che utilizza ExpressJS è fondamentale per mantenere il codice pulito, scalabile e manutenibile. In questo articolo vedremo come organizzare un'applicazione Express in modo modulare, separando le responsabilità in diversi file e cartelle.
1. Struttura delle cartelle
Una struttura modulare consigliata può essere la seguente:
my-app/
├── app.js
├── routes/
│ ├── index.js
│ └── users.js
├── controllers/
│ ├── userController.js
├── models/
│ └── user.js
├── middlewares/
│ └── auth.js
└── config/
└── db.js
2. Punto di ingresso: app.js
Il file app.js è il punto di partenza dell'applicazione. Qui configuriamo Express e montiamo le route.
const express = require('express');
const app = express();
const indexRoutes = require('./routes/index');
const userRoutes = require('./routes/users');
app.use(express.json());
app.use('/', indexRoutes);
app.use('/users', userRoutes);
app.listen(3000, () => {
console.log('Server in ascolto sulla porta 3000');
});
3. Routing
Ogni file all'interno della cartella routes/ gestisce un gruppo specifico di endpoint.
routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('Benvenuto nell\'API');
});
module.exports = router;
routes/users.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
router.get('/', userController.getAllUsers);
router.post('/', userController.createUser);
module.exports = router;
4. Controller
I controller contengono la logica applicativa per ciascuna route.
controllers/userController.js
const users = [];
exports.getAllUsers = (req, res) => {
res.json(users);
};
exports.createUser = (req, res) => {
const user = req.body;
users.push(user);
res.status(201).json(user);
};
5. Middleware
I middleware possono essere definiti separatamente per funzioni riutilizzabili, come l'autenticazione.
middlewares/auth.js
module.exports = (req, res, next) => {
const token = req.headers['authorization'];
if (token === 'segreto') {
next();
} else {
res.status(401).json({ message: 'Non autorizzato' });
}
};
6. Configurazione e modelli
Tutte le configurazioni (come la connessione al database) dovrebbero stare in config/, mentre i modelli di dati in models/.
config/db.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/mydb', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
models/user.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String,
});
module.exports = mongoose.model('User', userSchema);
Conclusione
Strutturare un'app ExpressJS in modo modulare permette di avere un codice più chiaro, testabile e facile da estendere. Separare routing, controller, middleware e configurazione è una buona pratica che migliora la qualità del software, specialmente in progetti di medio-grandi dimensioni.