Dal tema della rivista alla pratica di progetto
Pagine di servizi e tecniche correlate all'articolo
Molte aziende si trovano oggi in una situazione simile: un’applicazione specialistica evoluta (spesso Delphi/VCL) mappa processi centrali, ma deve improvvisamente servire nuovi canali. Un portale clienti necessita di dati e procedure, gli utenti mobili si aspettano accessi sicuri, sistemi di terze parti (ERP, DMS, CRM, BI) richiedono integrazioni. In questa situazione una REST-API sembra il passo ovvio. In pratica le iniziative API falliscono però raramente per HTTP o JSON, bensì per una ripartizione delle responsabilità poco chiara tra client, server e persistenza dei dati.
Un’architettura di REST-Server sostenibile con Delphi non si ottiene mettendo “qualche endpoint” sopra tabelle esistenti. Si ottiene quando l’azienda considera congiuntamente regole di dominio, requisiti di sicurezza, sovranità dei dati, confini transazionali e concetti di esercizio. Il REST-Server diventa così il layer contrattuale stabile tra la logica di business e i consumatori: client desktop, portale, servizi, partner di interfaccia. Proprio qui Delphi mostra i suoi punti di forza: sviluppo rapido, runtime robusto, codice nativo performante, buona integrazione con il database (p.es. tramite BDE-Ablösung con connessione nativa) e la possibilità di incapsulare la logica di dominio in librerie o moduli server in modo controllato.
Questo contributo descrive come le aziende possano pianificare REST-Server con Delphi in modo da rimanere coerenti dal punto di vista funzionale, integrarsi nei paesaggi di sistema esistenti e non diventare fonte di guasti in esercizio. L’attenzione è su principi architetturali, insidie tipiche nei progetti di modernizzazione e componenti concreti per sicurezza, accesso ai dati, versioning e osservabilità.
Perché una REST-API è una decisione architetturale per l’azienda
In un mondo client-server classico molte regole erano implicitamente distribuite nel client desktop: validazioni, transizioni di stato, calcoli, a volte persino controlli di autorizzazione. Finché esisteva un solo client non era critico — funzionalmente discutibile, ma gestibile. Quando più consumatori accedono agli stessi oggetti di business, il modello salta:
- Un portale non può “riutilizzare” le validazioni del client.
- Le app mobili devono poter funzionare offline, ma non devono duplicare regole di dominio.
- Le integrazioni richiedono contratti stabili e versionati e una semantica degli errori chiara.
- La compliance richiede accessi tracciabili, modelli di ruolo e audit.
L’API diventa il punto in cui convergono logica di dominio, diritti e accesso ai dati. La sua architettura decide quindi se il vostro sistema resterà ampliabile nel tempo o se genererà nuovo debito tecnico.
Delphi come piattaforma per REST-Server: punti di forza e scenari tipici
Delphi è spesso associato ad applicazioni desktop. Per REST-Server, tuttavia, Delphi è altrettanto adatto, specialmente quando si riutilizza logica esistente o si richiedono servizi performanti. Scenari tipici in ambienti B2B:
- Layer API per software esistente: l’applicazione specialistica Delphi rimane come UI, il REST-Server incapsula accessi ai dati e regole per nuovi consumatori.
- Backend per portali/aree clienti: il portale web utilizza endpoint REST che impiegano lo stesso nucleo regolamentare dei processi interni.
- Server di integrazione e interfacce: connessione a ERP/DMS/CRM, import/export, elaborazione eventi, job schedulati.
- Linux-Services o Windows Services: processi a lunga durata, worker su code, scheduler, workflow documentali.
Decisiva non è l’etichetta del framework, ma la disciplina nella stratificazione, nella concorrenza, nella gestione degli errori e nel deployment. Delphi consente entrambe le cose: iterazioni rapidamente consegnabili e al contempo architetture pulite e modulari — se pianificate consapevolmente.
Modello a strati: Layer-3 come base per API durature
Per il software aziendale si è dimostrato valido un modello a strati chiaro e snello. Nell’ambiente Delphi questo è spesso descritto come Layer-3 Architektur. I termini possono variare, ma le responsabilità devono essere inequivocabili:
1) API-/Transport-Layer (HTTP, Serialization, Routing)
Questo layer gestisce HTTP, autenticazione a livello di protocollo, formati request/response, routing, status code, Content-Type, compressione. Qui non devono risiedere regole di dominio. Obiettivo: intercambiabilità e testabilità. Se in futuro estendete una REST-API con protocolli complementari (p.es. WebSocket, pattern simili a gRPC, Server-Sent Events), il nucleo funzionale deve restare stabile.
2) Domain-/Service-Layer (logica di dominio, casi d’uso, diritti, transazioni)
Qui risiede la verità funzionale: macchine a stati, calcoli, plausibilità, regole multi-tenant, controlli di autorizzazione su azioni di dominio. Questo layer dovrebbe essere indipendente dalla UI e lavorare idealmente senza conoscenza di HTTP. È preferibile implementare casi d’uso come “rilasciare ordine”, “chiudere ticket”, “generare fattura” piuttosto che limitarsi a operazioni CRUD sulle tabelle.
3) Data-Access-Layer (Repository, SQL, FireDAC, mapping)
Questo layer incapsula la persistenza: SQL, stored procedure, controllo delle transazioni, concetti di locking, connection pooling, peculiarità specifiche DB. In Delphi BDE-Ablosung mit nativer Anbindung è spesso la scelta pragmatica, in particolare nelle migrazioni (Ablösung di BDE) e in presenza di database eterogenei (SQL Server, PostgreSQL, MariaDB, Firebird). È importante che il Data-Access-Layer non contenga conoscenze HTTP né prenda decisioni di business.
Questo modello riduce l’accoppiamento: le modifiche al modello dati non obbligano a riscrivere l’API, e nuovi client ereditano automaticamente la stessa logica. Soprattutto nella Delphi Modernisierung è la base per disaccoppiare gradualmente applicazioni desktop consolidate senza interrompere l’esercizio.
Progettazione API per software aziendale: non CRUD ma contratti funzionali
Molte API partono con endpoint come /customers, /orders, /documents e implementano CRUD. Per strumenti interni può essere sufficiente, ma nel software aziendale risulta rapidamente troppo superficiale. I processi di business sono composti da transizioni di stato, regole, effetti collaterali e autorizzazioni.
Modellare risorse, azioni e stati in modo chiaro
Un pattern migliore è la combinazione di risorse e azioni esplicite, ad esempio:
- Leggere una risorsa: GET /orders/{id}
- Innescare un’azione: POST /orders/{id}/release
- Generare un documento: POST /orders/{id}/documents/invoice
- Controllare lo stato: GET /orders/{id}/status
Così nel contratto API diventa evidente che “rilasciare” non è semplicemente un aggiornamento di campo. Il server può implementare centralmente validazioni, diritti, transazioni, audit e processi secondari.
Semantica degli errori e validazione: rendere gli errori pianificabili per i client
I client aziendali devono poter distinguere gli errori: errori di validazione (400), permesso negato (403), conflitto dovuto a modifiche parallele (409), rifiuto funzionale (spesso 409 o 422), problemi temporanei del backend (503). Importante è una struttura di errore coerente, p.es. con codice di errore, messaggio, eventuali indicazioni sui campi e una correlation ID. Così un portale può mostrare messaggi comprensibili e contemporaneamente il supporto e l’esercizio possono tracciare efficacemente il problema.
Sicurezza: autenticazione non equivale ad autorizzazione
Nei contesti B2B la sicurezza raramente fallisce per la mancanza di cifratura, ma piuttosto per l’assenza di separazione tra identità, ruoli e autorizzazioni di dominio. Un’architettura di REST-Server deve quindi distinguere almeno due livelli:
Autenticazione (chi è?)
Procedure comuni sono approcci basati su token (p.es. JWT o token opachi), combinati con TLS e una strategia di sessione chiara. Decisivo è: durata del token, meccanismo di refresh, invalidazione a seguito di cambi di ruolo e la scelta se usare provider di identità distinti per portali e sistemi interni. Delphi-Server possono comportarsi sia da resource server sia — a seconda dell’architettura — da issuer di token. In molte infrastrutture aziendali l’integrazione con sistemi di identity esistenti (p.es. AD/LDAP, soluzioni SSO) è un punto centrale.
Autorizzazione (può farlo?)
L’autorizzazione appartiene al Domain-/Service-Layer. Ruoli e permessi raramente sono puramente tecnici; dipendono da tenant, sede, unità organizzativa, stato contrattuale o fase di processo. Buone pratiche:
- Modello di ruoli (p.es. Admin, Operatore, Auditor) come base
- Policy funzionali (“può generare fattura solo nello stato X”, “può vedere solo i propri ticket”)
- Multi-tenancy come default: ogni request richiede il contesto tenant
- Auditing: chi ha eseguito quale azione e quando
L’API non dovrebbe limitarsi a restituire “accesso consentito/negato”, ma impedire al server che, tramite manipolazioni di parametri, vengano rese visibili informazioni di altri tenant. Può sembrare ovvio, ma nei sistemi ereditati è uno degli errori architetturali più comuni quando si espongono “tabelle su HTTP” troppo in fretta.
Accesso ai dati con FireDAC: transazioni, pooling e strategia DB
Nelle applicazioni aziendali l’accesso ai dati è il fattore di stabilità: picchi di carico, deadlock, report lunghi, aggiornamenti paralleli, import batch. FireDAC è nell’ecosistema Delphi un componente collaudato per servire diversi database con accesso uniforme. Per un’architettura di REST-Server sono particolarmente rilevanti i seguenti punti:
Confini transazionali per caso d’uso
Una REST-API è tipicamente basata su request. Questo si sposa bene con “una transazione per caso d’uso”: all’interno di una request si apre una transazione, si eseguono le operazioni funzionali, poi commit/rollback. Importante: non mettere automaticamente ogni endpoint in una transazione, ma essere coerenti per le operazioni di scrittura. Gli endpoint di lettura possono richiedere transazioni a seconda del livello di isolamento necessario per viste consistenti.
Strategia di connessione e parallelismo
La parallelità lato server implica molte richieste concorrenti, ognuna con accesso al DB. Pianificate quindi:
- pool con dimensioni limitate e monitorate
- timeout per query e connessioni
- regole chiare per operazioni di lunga durata (estrarle in job/worker)
Un errore frequente è eseguire report costosi o esportazioni massicce sincronamente sulla stessa istanza API che serve richieste interattive del portale. Meglio separare: interattivo vs. batch/async.
Modernizzazione del database come parte della pianificazione API
Se nell’installato esistono ancora accessi datati (p.es. BDE), l’API può diventare un catalizzatore: costringe a definire confini d’accesso ai dati. Una sostituzione controllata verso FireDAC riduce i rischi e aumenta la portabilità (PostgreSQL, MariaDB, SQL Server). Importante non pianificare tutto come Big Bang, ma progressivamente: i nuovi use case server utilizzano il nuovo Data-Access-Layer mentre le parti legacy migrano a seguire.
Versioning e retrocompatibilità: i contratti API proteggono
Le aziende sottovalutano spesso quanto siano costose le breaking change. Quando un portale clienti, un sistema partner o un Windows- und Linux-Services si basa sulla vostra API, non potete più “rinominare” campi a cuor leggero. Una strategia di versioning pulita è quindi obbligatoria.
Regole pragmatiche per il versioning
- Niente breaking change senza versione: non rinominare/rimuovere campi, non reinterpretare endpoint.
- Estendere invece di modificare: aggiungere nuovi campi, segnare i vecchi come deprecati.
- Defaults compatibili: evitare nuovi campi obbligatori o derivarli server-side.
- Versioning esplicito: p.es. /v1/… o tramite header; più importante della tecnica è la coerenza.
Per i team Delphi questo significa anche: mantenere stabili i DTO (Data Transfer Objects) e progettare il mapping in modo consapevole, invece di serializzare 1:1 gli oggetti di dominio. Aumenta lo sforzo iniziale, ma riduce i costi di supporto nel lungo periodo.
Observability: log, metriche e trace fin dall’inizio
In un esercizio produttivo “funziona da me” non serve a nulla se gli errori non sono riproducibili. I REST-Server che servono molti consumatori richiedono almeno un livello minimo di osservabilità:
Logging strutturato con correlation ID
Ogni request dovrebbe portare una correlation ID (accettare quella in ingresso o generarne una) e ritrovarsi nei log. Le voci di log dovrebbero essere strutturate (p.es. log JSON) per poter essere ingerite in sistemi centrali. Minimo utile:
- metodo request, route, status code, durata
- contesto utente/tenant (pseudonimizzato/conforme alle regole)
- durata DB e classe di errore
- correlation ID per il supporto
Metrica per capacità e trend di errore
Per scalare e mantenere stabilità servono metriche: richieste al minuto, latenze p95/p99, tassi di errore per endpoint, utilizzo pool DB, lunghezza code. Non serve un approccio “Cloud-Native Overkill”, ma senza numeri le discussioni sulle prestazioni diventano opinioni.
Gestione errori ed eccezioni come componente architetturale
Le eccezioni Delphi non devono trapelare senza controllo verso l’esterno. Una exception-middleware centrale (o un handler globale) dovrebbe tradurre le eccezioni in risposte di errore coerenti, incluse support-ID e codici HTTP sensati. Internamente gli stacktrace devono finire in log sicuri, non nelle risposte ai client.
Sincrono vs asincrono: estrarre i processi lunghi dalla risposta REST
Molti processi aziendali non sono “request/response in 200 ms”: generazione PDF, import dati, corse di interfacce, riconciliazioni, modifiche massicce, archiviazione. Questi carichi raramente appartengono a un endpoint REST sincrono, perché vincolano thread, provocano timeout e bloccano l’utente.
Pattern Job
Pratica consolidata: un endpoint avvia un job e il server restituisce immediatamente un job-ID. Un altro endpoint fornisce stato/risultato. Opzionalmente un callback/webhook notifica. In Delphi questo si realizza con worker-service, una tabella job e una macchina a stati chiara. Vantaggio: stabilità e scalabilità prevedibile.
Code e servizi
Secondo il contesto una message queue può essere utile, ma non è obbligatoria. Fondamentale è il principio: le API interattive restino reattive, i processi batch girino in modo controllato, ripetibile e osservabile — come Windows Services o Linux-Services a seconda del deployment.
Deployment in azienda: Windows, Linux, container, on‑prem
Un’architettura di REST-Server è completa solo se è esercitabile. Le aziende differiscono: server classici Windows, host virtualizzati Linux, piattaforme container, zone di rete rigidamente separate, requisiti di proxy e certificati. Delphi è flessibile in questo contesto, a patto di controllare le dipendenze.
Configurazione e secret
La configurazione deve essere dipendente dall’ambiente (Dev/Test/Prod). Credenziali non devono trovarsi in EXE o repository. Usate archiviazione sicura (p.es. secrets management della piattaforma) e separate i valori di configurazione dai rilasci di codice. Pianificate anche la rotazione (password DB, API-Key) senza dover ricostruire il sistema.
Strategie di release e rollback
Se più consumatori dipendono da un’API servono rilasci controllati: script di migrazione DB, feature toggle per attivazioni progressive, percorsi di rollback chiari. In particolare le modifiche al DB devono essere retrocompatibili se si vuole mantenere la possibilità di rollback della versione server.
Integrazione con il software esistente: modernizzazione graduale invece di Big Bang
In molte realtà Delphi il nucleo funzionale è prezioso ma tecnicamente “incollato”: accessi al DB legati all’UI, stati globali, responsabilità miste. Un’API REST può essere al contempo rischio e opportunità. L’obiettivo è definire un percorso che con sforzo contenuto fornisca miglioramenti misurabili.
Strangler-approach per le API
Invece di rifare tutto, definite punti di interfaccia funzionali che portino reale valore: p.es. “stato ordine e documenti per il portale clienti”, “lookup anagrafiche per utenti mobili”, “interfaccia per registrazioni ERP”. Questi use case diventano nuove funzioni API, complete di Domain-Layer e Data-Access. Il client legacy può migrare gradualmente agli stessi use case server senza che l’UI debba essere riscritta immediatamente.
Logica condivisa: utile, ma controllata
Delphi permette di usare librerie di logica sia sul server sia nelle applicazioni esistenti. Può essere un ponte, ma comporta rischi: se dipendenze di UI penetrano nella logica condivisa si perde il disaccoppiamento. Una regola chiara: condividere solo logica priva di UI, senza stati globali, con interfacce nette e unità testabili. Il resto rimane separato.
Errori tipici nei progetti di REST-Server — e come evitarli
“Pubblicheremo semplicemente le tabelle”
Se gli endpoint riflettono direttamente le tabelle si ottiene un sistema instabile: ogni refactoring DB è breaking change per l’API, le regole di dominio si duplicano nei client e gli input non verificati aprono falle di sicurezza. Meglio: casi d’uso di dominio e DTO che stabilizzino il contratto.
Autorizzazioni di dominio solo nel client
I client sono intercambiabili e manipolabili. L’autorizzazione deve risiedere nel server e considerare regole di dominio, non soltanto ruoli tecnici.
Mancanza di strategia per la concorrenza
Le modifiche parallele avvengono: due operatori, portale e client interno, o un job di import. Senza optimistic locking (p.es. RowVersion/Timestamp), codici di conflitto (409) e regole di merge si rischiano perdite di dati o comportamenti “ultimo scrittore vince”.
I processi lunghi bloccano gli endpoint interattivi
Generazione PDF sincrona o esportazioni portano a timeout e a esperienze “bloccate”. Meglio il pattern Job con endpoint di stato.
L’osservabilità viene aggiunta a posteriori
Senza correlation ID, log strutturati e metriche ogni guasto diventa una caccia. L’osservabilità non è un lusso, ma un prerequisito operativo.
Checklist concreta per la vostra architettura di REST-Server con Delphi
- Separare chiaramente gli strati: Transport (HTTP), Domain (Use Cases), Data Access (FireDAC/SQL).
- Comprendere l’API come contratto: mantenere stabili i DTO, pianificare il versioning, evitare breaking change.
- Sicurezza a due stadi: autenticazione (token) e autorizzazione (policy funzionali, tenant).
- Impostare consapevolmente le transazioni: per caso d’uso, timeout, strategia di conflitto.
- Estrarre i processi lunghi in asincrono: job/worker, Windows- o Linux-Services.
- Integrare l’osservabilità: correlation ID, log strutturati, metriche, gestione centralizzata degli errori.
- Pianificare realisticamente il deployment: configurazione/secrets, rollback, migrazioni DB.
- Modernizzare in modo iterativo: prima use case di valore, disaccoppiare le parti legacy gradualmente.
Conclusione: i REST-Server valgono quando sono architettura di esercizio e di dominio
Un’architettura di REST-Server con Delphi è particolarmente efficace per le aziende quando non è intesa come una “superficie tecnica”, ma come nucleo che connette processi, dati e canali. Fondamentali sono strati puliti (Layer-3 Architektur), endpoint modellati funzionalmente, logica di sicurezza e multi-tenancy coerente, e un modello operativo con versioning, monitoring e gestione controllata della concorrenza. Così l’API diventa una piattaforma stabile: per portali, integrazioni, servizi e per la modernizzazione graduale Delphi Modernisierung — senza mettere a rischio la sostanza funzionale di un sistema cresciuto nel tempo.
Se volete valutare come impostare una REST-API robusta sulla vostra infrastruttura Delphi esistente (inclusi strategia DB, FireDAC, servizi e esercizio), contattateci qui: https://net-base-software-gmbh.de/kontakt/
Passo successivo
Quando un tema diventa un progetto reale, architettura, sistemi esistenti e gestione operativa dovrebbero essere considerati insieme fin dalle fasi iniziali.
Non forniamo solo supporto per questioni isolate, ma anche quando da frammenti di codice sorgente, tematiche legacy o idee di portale deve nascere un progetto aziendale solido.
- Stato attuale, stato obiettivo e rischi tecnici vengono valutati insieme.
- REST, l'accesso ai dati, i portali e il rollout non vengono rinviati a fasi successive.
- Vede in anticipo quale percorso è economicamente e operativamente sostenibile.