f in x
API REST Node.js — Versioning e OpenAPI per API che Non si Rompono in Produzione
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Sviluppo di siti web

API REST Node.js — Versioning e OpenAPI per API che Non si Rompono in Produzione

[2026-06-23] Author: Ing. Calogero Bono

Hai mai rilasciato una modifica a un'API e scoperto che il client mobile si rompe? O peggio: hai ereditato un backend Node.js senza documentazione e passi ore a leggere codice e fare tentativi? Se lavori con API REST in Node.js, prima o poi ti scontri con due problemi: come far evolvere l'API senza rompere i client esistenti e come tenere traccia di cosa fa ogni endpoint. Versioning e OpenAPI non sono optional — sono la differenza tra un'API che scala e un bordello di endpoint che nessuno capisce più.

Noi, di Meteora Web, lo vediamo ogni giorno nei progetti che ci arrivano. API senza versioning, documentazione assente o scritta a mano su un Google Doc già obsoleto. E poi il caos: client che chiamano endpoint deprecati, errori 500 misteriosi, sviluppatori che hanno paura di toccare il backend. Con Node.js ed Express, abbiamo messo a punto un flusso che risolve entrambi i problemi in modo pulito e sostenibile.

Perché versionare le API REST in Node.js?

Il motivo è uno solo: non rompere i client che dipendono dalla tua API. Quando pubblichi un endpoint, qualcuno (app mobile, frontend React, integrazione con terze parti) fa affidamento su quella struttura di dati, su quei nomi di campo, su quel comportamento. Se cambi tutto senza preavviso, prepari un incidente.“Ma possiamo mettere un campo nuovo in più” — certo, ma una modifica di campo obbligatorio, rimozione di un campo, cambio di tipo, sono breaking change. Senza versioning, l'unica alternativa è non modificare mai, e l'API diventa un fossile.

Sponsored Protocol

Noi partiamo sempre da una domanda: quanto costa un incidente di integrazione? Conti alla mano, un giorno di debug collettivo tra team frontend e backend costa più di un'ora di setup del versioning. Dopo otto anni di progetti, abbiamo scelto la strada pragmatica.

Quali strategie di versioning funzionano per API Node.js?

Le tre strategie classiche sono: URL path, query parameter e header custom. Ecco come si comportano su Express.

Versioning via URL path (il più diffuso)

Esempio: /api/v1/users, /api/v2/users. Semplicissimo, visibile, facilmente testabile a mano. Noi lo usiamo nella maggior parte dei progetti perché è trasparente anche per client non tecnici.

const express = require('express');
const app = express();

// V1: restituisce nome e email
const routerV1 = express.Router();
routerV1.get('/users/:id', (req, res) => {
  res.json({ id: req.params.id, name: 'Mario', email: 'mario@example.com' });
});

// V2: aggiunge telefono (breaking change per chi si aspettava solo name/email)
const routerV2 = express.Router();
routerV2.get('/users/:id', (req, res) => {
  res.json({ id: req.params.id, name: 'Mario', email: 'mario@example.com', phone: '+39...' });
});

app.use('/api/v1', routerV1);
app.use('/api/v2', routerV2);

Pro: chiaro, cacheable, facile da versionare anche a livello di gateway. Contro: se hai tante versioni, lo schema URL si allunga e duplica codice. Per gestirlo, isoliamo i router in file separati e usiamo un versions/index.js che mappa la versione al router corretto.

Sponsored Protocol

Versioning via header (Accept o custom)

Esempio: header Accept: application/vnd.api+json;version=2. Più pulito dal punto di vista RESTful, perché la URL rappresenta la risorsa, non la sua forma. Ma è invisibile a un semplice curl senza explicitarlo, e rende i log meno immediati. Lo riserviamo a API interne o quando il cliente è solo un'app mobile ben controllata.

app.get('/users/:id', (req, res) => {
  const version = req.headers['accept-version'] || '1';
  if (version === '2') {
    res.json({ id: req.params.id, name: 'Mario', email: 'mario@example.com', phone: '+39...' });
  } else {
    res.json({ id: req.params.id, name: 'Mario', email: 'mario@example.com' });
  }
});

Pro: URL pulita, versioning senza cambiare route. Contro: difficile da debuggare, cache più complessa, client deve sapere esattamente cosa inviare.

Versioning via query parameter

/api/users?version=2. Sconsigliato: polluisce il significato della query (che dovrebbe servire per filtri e paginazione), ed è facilmente dimenticato dal client. Noi lo evitiamo.

Come documentare le API REST con OpenAPI in Node.js?

Avere le versioni è inutile se non sai cosa fa ciascuna versione. OpenAPI (ex Swagger) risolve il problema: un file YAML/JSON che descrive ogni endpoint, parametri, risposte, schemi. E con swagger-jsdoc e swagger-ui-express generi la documentazione interattiva direttamente dal codice.

Sponsored Protocol

Ci vediamo spesso progetti dove la documentazione è un PDF di due anni fa. Noi integriamo OpenAPI nel ciclo di sviluppo: ogni rotta ha i commenti JSDoc che generano lo spec. Zero sforzo extra, documentazione sempre sincronizzata.

Setup rapido con Express

npm install swagger-jsdoc swagger-ui-express

Configurazione openapi.js

const swaggerJsdoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'API MyApp',
      version: '1.0.0',
      description: 'Documentazione API MyApp',
    },
    servers: [
      { url: 'http://localhost:3000/api/v1', description: 'Development server V1' },
      { url: 'http://localhost:3000/api/v2', description: 'Development server V2' },
    ],
  },
  apis: ['./routes/*.js'], // dove metti i commenti JSDoc
};

const spec = swaggerJsdoc(options);

module.exports = { swaggerUi, spec };

Documentare una rotta con JSDoc

In routes/users.js:

/**
 * @openapi
 * /users/{id}:
 *   get:
 *     description: Recupera un utente per ID
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Utente trovato
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 id:
 *                   type: string
 *                 name:
 *                   type: string
 *                 email:
 *                   type: string
 *       404:
 *         description: Utente non trovato
 */
router.get('/users/:id', (req, res) => {
  // ...
});

Montare Swagger UI

const { swaggerUi, spec } = require('./openapi');

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(spec));

// Opzionale: esportare lo spec come JSON
app.get('/api-docs.json', (req, res) => res.json(spec));

Ora hai un'interfaccia interattiva su /api-docs dove ogni endpoint è testabile. La documentazione si aggiorna ogni volta che modifichi i commenti JSDoc.

Sponsored Protocol

Come gestire versioni multiple nella documentazione OpenAPI?

Un solo file OpenAPI può descrivere tutte le versioni, usando paths distinti per /api/v1/users e /api/v2/users. Oppure puoi mantenere file separati. Noi preferiamo un solo spec con servers multipli e tags per versione.

tags:
  - name: v1
    description: Endpoint versione 1
  - name: v2
    description: Endpoint versione 2
paths:
  /users/{id}:  # attenzione: base path è già incluso dal server
    get:
      tags: [v1]
      # ...
  /users/{id}:
    get:
      tags: [v2]
      # ...

Nell'implementazione JSDoc, puoi annotare ogni rotta con il tag appropriato. La UI mostra il menu a tendina per scegliere il server.

Quali best practice seguire per versioning e documentazione in produzione?

  • Versiona solo quando c'è un breaking change. Aggiungere campi opzionali non richiede nuova versione. Rimuovere o cambiare tipo sì.
  • Depreca le versioni vecchie in modo graduale. Includi header Sunset e Deprecation nelle risposte delle versioni che intendi disattivare. Documentalo nello spec con deprecated: true.
  • Non tenere più di 2 versioni attive (salvo contratti lunghi). Gestire versioni vecchie costa manutenzione, errori e debito tecnico.
  • Automatizza la generazione dello spec. Noi lo inseriamo in una pipeline CI: a ogni push, lo spec viene validato con swagger-cli e pubblicato su un endpoint interno.
  • Usa express-openapi-validator per validare richieste e risposte contro lo spec. Previeni errori in produzione.

Cosa fare adesso

  1. Scegli una strategia di versioning — per l'80% dei progetti, URL path va benissimo. Implementala subito nel router di Express.
  2. Installa swagger-jsdoc e swagger-ui-express e configura lo spec base. Documenta almeno un endpoint a scopo formativo.
  3. Aggiungi i commenti JSDoc a tutte le rotte esistenti. Puoi farlo gradualmente, ma inizia da quelle esposte a cliente.
  4. Disponi lo spec pubblicamente (protetto da basic auth se sensibile) e condividilo con team frontend e mobile.
  5. Pianifica un deprecation cycle per eventuali versioni vecchie. Imposta header di deprecation e comunica le scadenze.

Se vuoi vedere un esempio funzionante completo di versioning e OpenAPI con Node.js, torna alla nostra guida principale su Node.js per il backend. Lì trovi il contesto più ampio.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()