Ci sono due modi di sbagliare l'architettura dei contenuti e la maggior parte dei progetti ne sceglie uno. Da una parte i puristi del tutto-in-Git, per cui correggere un refuso significa un branch, una pull request e un deploy completo. Dall'altra chi decide che il CMS debba contenere tutto — stringhe di interfaccia, configurazione del layout, design token, ogni cosa — finché il sito non riesce a mostrare un pulsante senza un giro sulla rete. Ho costruito il mio portfolio e questo blog sullo stesso livello di contenuti, e l'unica cosa che ha retto è un confine netto tra i due.
All'inizio, tutto ciò che costruivo viveva in file dentro il repository — INI, poi JSON —, tutto sotto controllo di versione e interamente nelle mie mani. Era semplice finché non lo è stato più. Il giorno in cui vuoi correggere una frase dal telefono, o pubblicare un pensiero senza aprire un editor, il contenuto solo-in-file diventa un muro. Forzare un deploy per spostare una virgola è uno spreco di deploy.
Così la prima volta che ho preso in mano un CMS headless ho corretto troppo e ci ho messo tutto — etichette di UI, impostazioni del tema, stato dei componenti —, in tabelle remote accanto al testo vero. Questo scambia una modalità di guasto con una peggiore. Ora il chrome dell'interfaccia arriva via rete, l'internazionalizzazione è una chiamata API, e un singhiozzo del CMS può far cadere una pagina che non ha motivo di dipendere dal CMS. La risposta non è mai stata una parte o l'altra. È un contratto tra ciò che cambia ogni giorno e ciò che definisce il sistema.
Il CMS riceve i contenuti narrativi e mutevoli, e nient'altro — le cose che crescono e cambiano senza che nessuno debba rifattorizzare. In questo blog è ogni articolo, estratto e argomento: scrivo e pubblico da una schermata di amministrazione senza toccare il codice sorgente. Nel portfolio sono le descrizioni dei progetti, le tappe, le competenze; finire un contratto è una modifica di contenuto, non una release. È anche la sede giusta per le poche impostazioni globali che devono cambiare senza un deploy: un annuncio, i metadati dell'autore, un feature flag. Se potrei bozzarlo, rivederlo o cancellarlo per capriccio, appartiene al database.
Tutto ciò che decide come si comporta l'applicazione, o che ha bisogno che il compilatore lo verifichi, resta nel codice. Il dizionario dell'interfaccia è il caso più chiaro: entrambi i siti sono localizzati in sei lingue, ma le etichette di navigazione, i testi dei pulsanti, i placeholder e gli aria-label vivono in JSON tipizzato nel repository, perché recuperarli da un CMS aggiungerebbe latenza al rendering della cornice e rischierebbe una chiave mancante a metà idratazione. Lo stesso vale per le regole di routing, la configurazione dei temi, i tempi delle animazioni, gli schemi di validazione: vogliono un controllo in fase di compilazione, non una riga di database. E gli asset statici: immagini, icone e miniature appartengono al progetto, dove la build può ottimizzarli e la cache può fidarsi di loro, senza un giro sui media del CMS nel percorso di rendering.
Alcune cose non entrano in nessuna scatola. Commenti, like, contatori di visualizzazioni, registri di rate-limit, sessioni — ad alta frequenza, transazionali, che richiedono vera integrità — non appartengono a un CMS pensato per scrivere né a file ricostruiti a ogni deploy. I thread di commenti hanno bisogno di risposte, controlli di autenticazione, moderazione. Un contatore di like schiaccerebbe una ricostruzione statica e arrancherebbe attraverso un'API di scrittura di un CMS. I rate limit e i log di accesso hanno bisogno di un vero database che fa vero lavoro in tempo reale. Quello è un terzo archivio, e fingere che sia uno degli altri due è il modo in cui si finisce con una versione lenta e fragile di entrambi.
Le storie vanno nel CMS. La struttura va nel codice. Tutto ciò che conta, scatta o limita va in un database che non fa nessuna di queste cose.
L'architettura è per lo più l'atto di tracciare linee e poi rifiutarsi di spostarle per comodità. Contenuto e codice hanno cicli di vita diversi; nel momento in cui smetti di fingere il contrario, gli strumenti smettono di combatterti. Il CMS mi lascia pubblicare da ovunque. Il repository tiene le parti che devono essere giuste in fase di build davvero giuste in fase di build. Il confine tra i due è l'unico motivo per cui l'uno o l'altro sono piacevoli da usare.
Le fondamenta sono gettate; ora si costruisce.