Perché ho spostato la generazione docx fuori da n8n: microservizi per necessità
Yuri Perfetti4 min0 lettureTempo di lettura: 6 minuti — Livello: intermedio/avanzato
Il contesto
Nell'articolo della settimana scorsa ho raccontato il bot Telegram che trasforma foto di documenti in file Word compilati. Oggi entro nel dettaglio della decisione architetturale più importante di quel progetto — quella che all'inizio mi sembrava una sconfitta e che si è rivelata la scelta migliore: estrarre la generazione dei .docx da n8n in un microservizio dedicato.
Lo racconto perché il percorso mentale è più utile del risultato: è il tipo di bivio davanti a cui prima o poi si trova chiunque automatizzi sul serio.
Atto primo: la strada "ovvia"
n8n ha i nodi Code, i nodi Code eseguono JavaScript, docxtemplater è una libreria JavaScript. Due più due: installo la libreria nell'immagine Docker, abilito i moduli esterni con NODE_FUNCTION_ALLOW_EXTERNAL, e genero i documenti dentro il workflow.
Ha funzionato. Per un po'.
Atto secondo: la piattaforma cambia sotto i piedi
Con n8n 2.x è arrivata una novità architetturale: i task runner, processi separati che eseguono il codice dei nodi Code in modo isolato. Ottima cosa per sicurezza e stabilità della piattaforma. Pessima notizia per il mio setup: l'accesso ai moduli esterni è diventato molto più rigido, e quello che prima era una variabile d'ambiente è diventato un percorso a ostacoli.
Ho fatto quello che fanno tutti: ho cercato workaround. Configurazioni dei runner, variabili aggiuntive, permessi. Ogni aggiornamento di n8n era una roulette: funzionerà ancora? La domanda giusta è arrivata dopo l'ennesima serata persa:
"Sto usando lo strumento, o sto combattendo contro lo strumento?"
Se la risposta è la seconda per più di due sessioni di fila, il problema non è la configurazione. È il design.
Atto terzo: il microservizio
La soluzione: un container minuscolo, Node + Express, ~100 righe di codice, un solo compito.
// Il cuore del servizio, concettualmente:
app.post("/generate", (req, res) => {
const { template, data } = req.body;
const doc = compilaTemplate(template, data); // docxtemplater
res.setHeader("Content-Type",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document");
res.send(doc);
});
Vive sulla stessa network Docker di n8n, quindi il workflow lo chiama per nome (http://docx-service:3000/generate) con un normale nodo HTTP Request. Nessuna porta esposta all'esterno, nessun modulo esterno dentro n8n, nessuna dipendenza dalle politiche dei task runner.
Perché è meglio, in concreto
Aggiornamenti indipendenti. n8n si aggiorna quando vuole n8n; il servizio docx non lo tocco da mesi perché non ha motivo di cambiare. Prima, ogni upgrade di n8n metteva a rischio la generazione documenti. Ora sono due destini separati.
Debugging chirurgico. Se un documento esce sbagliato, testo il servizio da solo con una chiamata curl, senza scomodare il workflow. Se il workflow fallisce, so che il problema è nell'orchestrazione. I confini netti trasformano "qualcosa non va" in "so dove guardare".
Riusabilità. Il servizio non sa nulla di Telegram né di n8n: riceve JSON, restituisce Word. Oggi lo chiamano più workflow diversi, e domani potrebbe chiamarlo un sito web o uno script. Un pezzo costruito una volta, usato ovunque.
Testabilità. Posso provarlo in locale con un JSON finto prima ancora di toccare il workflow. Sembra banale; non lo è quando il flusso completo coinvolge foto, IA e messaggi.
Il rovescio della medaglia (dovuto per onestà)
Un container in più è: un componente in più da avviare, monitorare, backuppare e ricordarsi che esiste. Per UN caso d'uso il conto torna facilmente; se l'istinto diventa "un microservizio per ogni cosa", finisci a gestire un condominio di container per un lavoro da monolocale. La soglia che uso io: estraggo un servizio quando la piattaforma mi rema contro oppure quando lo stesso pezzo serve a più flussi. Altrimenti, dentro n8n si sta benissimo.
La lezione trasferibile
Vale ben oltre n8n: ogni piattaforma — un CMS, un gestionale, un low-code qualsiasi — ha un perimetro dentro cui tutto è facile e fuori dal quale tutto è lotta. Il segnale che l'hai superato non è mai un errore chiaro: è la fatica ricorrente, il workaround che rompe, la configurazione che diventa folklore.
Quando lo riconosci, hai due opzioni: rientrare nel perimetro, o mettere fuori il pezzo ribelle con un'interfaccia pulita. Quasi mai la risposta giusta è la terza opzione, quella che scegliamo tutti d'istinto: spingere più forte.
Questo articolo fa parte della serie "Stack & Infrastruttura" su perfetti.tech — dove racconto quello che costruisco davvero, errori compresi.
Hai un problema simile?
Mandami due righe: ti dico se ha senso trasformarlo in uno strumento vero e quanto tempo serve.
Scrivimi →Commenti
Ancora nessun commento. Scrivi il primo!