Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Creare un'applicazione con il pattern MVC in Node.js e Express

Sfruttiamo il pattern MVC (Model-View-Controller) per realizzare un'applicazione completa con Node.js e Express
Sfruttiamo il pattern MVC (Model-View-Controller) per realizzare un'applicazione completa con Node.js e Express
Link copiato negli appunti

Nel mondo dello sviluppo software, mantenere ordine, separazione delle responsabilità e scalabilità è fondamentale, soprattutto man mano che un progetto cresce. Uno dei pattern architetturali più utilizzati per ottenere tutto questo è il pattern MVC, acronimo di Model-View-Controller.

Quando sviluppiamo applicazioni web con Node.js ed Express, il pattern MVC ci aiuta a organizzare il codice, separare la logica di business dalla presentazione e rendere il progetto facilmente manutenibile.

In questa guida costruiremo una semplice applicazione usando il pattern MVC con Node.js ed Express: un'applicazione di gestione di utenti (User Manager). Andremo passo passo, spiegando ogni parte del codice e l'organizzazione della struttura.

Cos'è il Pattern MVC?

Il pattern MVC divide la logica in tre componenti principali:

  1. Model: gestisce i dati e la logica di business.
  2. View: si occupa dell'interfaccia utente e della presentazione.
  3. Controller: riceve input, coordina il Model e aggiorna la View.
  4. Questa separazione favorisce una migliore organizzazione e facilita la collaborazione tra sviluppatori backend e frontend.

    Iniziamo il progetto

    Creiamo la cartella del progetto:

    mkdir user-manager-mvc
    cd user-manager-mvc
    npm init -y

    Installiamo i pacchetti:

    npm install express ejs body-parser

    • express
    • ejs
    • body-parser

    Struttura del progetto MVC

    Organizziamo il progetto come segue:

    user-manager-mvc/
    ├── app/
    │   ├── controllers/
    │   │   └── userController.js
    │   ├── models/
    │   │   └── userModel.js
    │   └── views/
    │       ├── index.ejs
    │       └── users.ejs
    ├── public/
    ├── routes/
    │   └── userRoutes.js
    ├── app.js
    ├── package.json

    Il file principale app.js
    // app.js
    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const userRoutes = require('./routes/userRoutes');
    // Imposta il motore di template EJS
    app.set('view engine', 'ejs');
    app.set('views', './app/views');
    // Middleware per dati POST
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(express.static('public'));
    // Route principali
    app.use('/', userRoutes);
    // Avvia il server
    app.listen(3000, () => {
      console.log('App in esecuzione su http://localhost:3000');
    });

    Qui stiamo dicendo ad Express di usare EJS

    Il Model: userModel.js
    // app/models/userModel.js
    let users = [];
    const User = {
      findAll: () => users,
      create: (name, email) => {
        const newUser = { id: Date.now(), name, email };
        users.push(newUser);
        return newUser;
      },
      findById: (id) => users.find(u => u.id === parseInt(id)),
      delete: (id) => {
        users = users.filter(u => u.id !== parseInt(id));
      }
    };
    module.exports = User;

    Questo model gestisce un array di utenti in memoria. In un'app reale useremmo un database, per semplicità qui usiamo un array.

    Controller: userController.js
    // app/controllers/userController.js
    const User = require('../models/userModel');
    exports.home = (req, res) => {
      res.render('index');
    };
    exports.listUsers = (req, res) => {
      const users = User.findAll();
      res.render('users', { users });
    };
    exports.createUser = (req, res) => {
      const { name, email } = req.body;
      User.create(name, email);
      res.redirect('/users');
    };
    exports.deleteUser = (req, res) => {
      const { id } = req.params;
      User.delete(id);
      res.redirect('/users');
    };

    Il controller gestisce le richieste del client e coordina il modello e la view. Notiamo funzioni per la home, la lista, la creazione e l'eliminazione utenti.

    Le Routes: userRoutes.js
    // routes/userRoutes.js
    const express = require('express');
    const router = express.Router();
    const userController = require('../app/controllers/userController');
    // Rotte
    router.get('/', userController.home);
    router.get('/users', userController.listUsers);
    router.post('/users', userController.createUser);
    router.post('/users/delete/:id', userController.deleteUser);
    module.exports = router;

    In questo file separiamo la logica delle route. Ogni URL è associato a una funzione del controller.

    Le View: index.ejs users.ejs

    index.ejs
    <!DOCTYPE html>
    <html>
    <head><title>Home</title></head>
    <body>
      <h1>Benvenuto</h1>
      <a href="/users">Gestione utenti</a>
    </body>
    </html>

    Ecco invece quella su users.ejs

    <!DOCTYPE html>
    <html>
    <head><title>Utenti</title></head>
    <body>
      <h1>Lista Utenti</h1>
      <form action="/users" method="POST">
        <input type="text" name="name" placeholder="Nome" required>
        <input type="email" name="email" placeholder="Email" required>
        <button type="submit">Aggiungi</button>
      </form>
      <ul>
        <% users.forEach(user => { %>
          <li>
            <%= user.name %> - <%= user.email %>
            <form action="/users/delete/<%= user.id %>" method="POST" style="display:inline;">
              <button type="submit">Elimina</button>
            </form>
          </li>
        <% }) %>
      </ul>
      <a href="/">Torna alla home</a>
    </body>
    </html&gt

    Le view sono in EJS e mostrano dinamicamente i dati del model. Vengono renderizzate dal controller.

    Test dell'applicazione

    node app.js

    Visitiamo ora l'indirizzo http://localhost:3000

    Vantaggi del Pattern MVC

    • Separazione delle responsabilità: ogni parte ha il suo ruolo.
    • Riutilizzabilità del codice: il controller può servire diverse view.
    • Facilità di test: i modelli possono essere testati indipendentemente.
    • Manutenibilità: con la crescita del progetto, l'organizzazione aiuta a non perdere il controllo.
    • Cosa abbiamo ottenuto

      Abbiamo realizzato insieme un'applicazione semplice ma solida seguendo il pattern MVC con Node.js ed Express. Questo approccio ci ha permesso di organizzare il codice in modo modulare, favorendo chiarezza, riutilizzabilità e manutenibilità. Attraverso il progetto abbiamo toccato con mano i vantaggi pratici dell'architettura MVC:

      • Il Model si occupa della gestione dei dati, in questo caso in memoria, ma facilmente sostituibile con un database reale come MongoDB o MySQL
      • Il Controller funge da intermediario intelligente, ricevendo richieste, processando dati tramite il model e decidendo quale view restituire.
      • La View, costruita con EJS, ci permette di mostrare in maniera dinamica i dati, fornendo una UI semplice ma efficace.
      • Seguendo questa struttura, ogni parte del progetto è facilmente modificabile o espandibile senza rompere le altre. Ad esempio, potresti sostituire EJS con un framework frontend come React o Vue, o collegare il model ad un database relazionale o NoSQL con modifiche minime.

        E ora? Cosa puoi fare dopo con il pattern MVC?

        Quello che hai visto è un punto di partenza solido. Da qui, le possibilità sono tantissime. Eccone alcune:

        • Persistenza dei dati: collega l'app a un database reale (es. MongoDB con Mongoose o PostgreSQL con Sequelize).
        • Autenticazione utenti: implementa login, registrazione e gestione delle sessioni con librerie come Passport.js o JWT.
        • Validazione dei dati: usa librerie come Joi per assicurarti che i dati ricevuti siano corretti prima di salvarli.
        • Refactoring in API REST: separa completamente la logica server dalle view per creare una vera API RESTful da consumare lato frontend.
        • Test automatizzati: inizia a scrivere test unitari per il Model e il Controller, migliorando la qualità del codice.
        • Deploy: pubblica l'app su un hosting e rendila accessibile online.

        Il pattern MVC è una colonna portante nello sviluppo web, padroneggiarlo in Node.js ti apre le porte per lavorare su progetti seri, sia personali che professionali. Saper strutturare bene un'app non è solo una buona pratica, ma è anche uno skill apprezzatissimo in ogni team di sviluppo.

        Non fermarti qui: continua a esplorare, sperimenta, migliora e.. costruisci!

Ti consigliamo anche