Fra magasinets tema til projektpraksis
Passende service- og tekniske sider til artiklen
Den, der vil rydde op i klient-server-arkitekturer i Delphi , står sjældent over for et „dårligt“ system. Ofte er der tale om robust forretningssoftware, der gennem årene er blevet udbygget, dækker mange specialtilfælde og fungerer pålideligt i daglig brug. Problemet opstår ikke på grund af Delphi som platform, men som følge af voksende ansvarsområder: klienten indeholder pludselig datalogik, „serveren“ er reelt kun en database, og grænseflader er blevet lagt til ad hoc. Det slår igennem, når nye sikkerhedskrav, databaseudskiftning, VPN til hjemmearbejde, terminalserver-opsætninger eller integrationer med ERP, DMS eller portaler kommer til.
Denne artikel viser, hvordan I praktisk og struktureret kan rydde op i Delphi-klient-server-landskaber: uden dogmatisk komplet genopbygning, men med klare mål for drift, administration, datakonsistens, grænsefladeegnethed og vedligeholdelse. Fokus er på beslutninger, som IT-ledelse og tekniske projektansvarlige kan styre: arkitekturgrænser, rollout-strategier, logning, rettighedskoncepter, migrationsveje og typiske risikokilder.
Hvordan man kan se, at klient-server-arkitekturen er „sammenvokset“
Tekniske gældsposter viser sig i driften ofte tidligere end i kildeteksten. Typiske signaler er mindre „dårlig kode“ end tilbagevendende gnidningspunkter mellem klient, database og infrastruktur:
- Uklare ansvarsområder: Klienten „ved“ for meget om tabeller, triggers, stored procedures eller endda stier til delte netværksplaceringer.
- Vanskelige releases: Hver lille ændring kræver rollout af klienten på mange arbejdspladser, ofte med manuelle trin.
- Sårbare dataadgange: Tilfældige deadlocks, inkonsistente transaktioner eller låse, der ikke frigives ved spidsbelastning.
- Sikkerhed som eftertanke: Databaseadgang foregår med for brede rettigheder; adgangskoder ligger i INI-filer; netværkssegmentering bryder funktioner.
- Integration er uforholdsmæssigt dyrt: Et kundesystem eller en REST-API er svær at eftermontere, fordi forretningsregler er fordelt.
- Vanskelig fejlsøgning: Uden pålidelig logning er det uklart, om fejl opstår i klienten, i netværket, i databasen eller i en grænseflade.
Hvis flere af disse punkter gør sig gældende, er „oprydning“ ikke kosmetik, men en foranstaltning for driftssikkerheden. Målet er ikke perfektion, men et system, der forbliver pålideligt muligt at ændre.
Klient-server i Delphi: Hvad der virkelig tæller i driften
I mange Delphi-landskaber forstås „klient-server“ implicit som „klienten taler direkte med databasen“. Det kan fungere – så længe rammebetingelserne ikke ændrer sig. For virksomheder tæller dog andre egenskaber:
- Skalerbarhed i dagligdagen: ikke højglans-benchmarks, men stabil ydeevne ved typiske belastningstoppe (månedsafslutning, vagtsskifte, importkørsler).
- Ændringsvenlighed: tilpasninger uden kædereaktion af rollout, datamigration og uddannelse.
- Sikker drift: gennemsigtige rettigheder, revisionssporbarhed, sikker håndtering af hemmeligheder (Credentials), klare netværksgrænser.
- Integrerbarhed: definerede grænseflader i stedet for en „anden klient“, der også kobler sig direkte til tabellerne.
Disse mål kan nås uden at „afløse“ Delphi. Det afgørende er, hvordan I trækker grænser: Hvad er UI, hvad er forretningslogik, hvad er dataadgang, og via hvilke grænseflader må andre systemer tilkoble?
Rydde op i client-server-arkitektur i Delphi: målbillede i stedet for Big Bang
Et praktisk målbillede er sjældent et radikalt snit. Et inkrementelt forløb med en klar arkitektramme har vist sig holdbart. Ofte implementeres det som en Layer-3-arkitektur: tre lag med klare ansvarsområder. „Layer“ betyder her: en defineret adskillelse af UI (præsentation), forretningslogik (regler/use-cases) og dataadgang (SQL, transaktioner, persistens). Det kan struktureres inden for en Delphi-monolit, før I trækker en egentlig service ud.
Trin 1: Gør arkitekturgrænser synlige
Før I ombygger, må I vide, hvor kobling opstår. Typiske grænseovertrædelser i Delphi-clients er:
- UI-hændelser (knapklik) indeholder SQL eller direkte tabeladgang.
- Forretningsregler er fordelt: delvis i klienten, delvis i triggere, delvis i rapporter eller importskripter.
- Databaseforbindelser åbnes overalt „ved siden af“, med forskellige parametre.
Målet er en overskuelig kerne: få indgangspunkt i forretningsfunktioner og en central dataadgang, der håndterer forbindelser, transaktioner og fejlbehandling konsekvent.
Trin 2: Definér „kontrakter“ – også uden services
Mange teams tror, at grænseflader først opstår med REST. I virkeligheden har I først brug for interne kontrakter: Hvilke funktioner findes, hvilke parametre overføres, hvilke fejlkoder er tilladt, hvilke transaktioner hører sammen? Disse kontrakter kan først eksistere som klart definerede moduler/byggeklodser i Delphi-projektet. Senere kan de relativt rent overføres til en REST-server eller til en Windows- og Windows- og Linux-services.
Stabilisere dataadgang: FireDAC, transaktioner og klar forbindelsesstrategi
Dataadgang er i client-server-opsætninger ofte den største løftestang for stabilitet. To temaer dominerer: konsistente forbindelser og rene transaktionsgrænser. I Delphi-miljøer er BDE-Ablösung med nativer tilslutning (dataadgangsbibliotek med drivere og forbindelsespooling) ofte moderniseringsankeret, især hvis stadig BDE (Borland Database Engine, et ældre dataadgangslag) er i brug.
BDE-Ablösung: Mere end et driverudskift
En BDE-Ablösung undervurderes, hvis man ser den som blot at „skifte komponenter ud“. I praksis berører den:
- SQL-dialekt og parameterisering: Forskellige databaser og drivere reagerer forskelligt på datoformater, NULL-håndtering, sortering og tegnsæt.
- Transaktionsadfærd: autocommit, isoleringsniveauer (regler for, hvor strengt låsning/læsning behandles) og fejlgenopretning.
- Ydeevne og låsninger: Noget gammel logik stoler ubevidst på implicitte låsemekanismer.
Operationelt vigtigt er et testkoncept, der ikke blot klikker gennem skærmbilleder, men simulerer typiske bogførings- og importforløb under belastning.
Transaktioner: Mindre magi, flere regler
I mange etablerede Delphi-clients opstår transaktioner tilfældigt: Et skærmbillede gemmer flere tabeller, men fejltilfælde rulles ikke ordentligt tilbage. Det fører til delvise datatilstande, som senere skal „manuelt ryddes op“. Bedre er et konsistent mønster:
- Én transaktion pr. faglig operation (f.eks. „Auftrag anlegen“, „Wareneingang buchen“), ikke pr. SQL-udtryk.
- Klare fejlforløb: Ved valideringsfejl ingen halvfærdig datatilstand, men kontrolleret afbrydelse.
- Idempotens ved import: Gentagen indlæsning uden dobbelte posteringer.
For IT-drift og support er det især væsentligt: Hvis en operation fejler, skal den fejle sporbar – med logposter, korrelerbare ID’er og en entydig fejlmeddelelsesklasse (f.eks. rettighed, datakonflikt, teknisk fejl).
Træk forretningslogik ud af klienten – uden at ødelægge betjeningen
Mange Delphi-clients er historisk vokset „UI-centreret“: Forløbet ligger i formularer, valideringer i OnChange-events, sideeffekter i OnExit. Det er fra brugerens synspunkt ofte hurtigt og direkte – men set fra arkitekturperspektiv svært at teste og udvide.
Use-Cases i stedet for formularlogik
Et praktisk mellemliggende skridt er at samle funktionaliteten i faglige Use-Cases: En Use-Case kapsler en operation (f.eks. „Rechnung freigeben“) inklusive valideringer, beregninger, dataadgang og protokollering. UI’en kalder den og viser resultater i stedet for selv at implementere reglerne. Fordel: Senere kan den samme Use-Case bruges via en REST-API, f.eks. til en portal eller en importtjeneste.
Centraliser regler: Validering, nummerserier, tilstandsmodeller
Typiske kandidater til centralisering er:
- Valideringsregler (obligatoriske felter, værdiområder, plausibilitetskontroller)
- Nummerserier (bilag, partier, processer) med konfliktundgåelse
- Tilstandsmodeller (Udkast → gennemgået → frigivet → bogført) med tilladte overgange
- Adgangskontroller tæt på forretningsoperationen, ikke kun i UI’en
Specielt for rettigheder er det afgørende: Hvis regler kun ligger i klienten, er de svære at holde konsistente for grænseflader, automatiseringer eller senere portaler.
Blive klar til integration: REST-API som kontrolleret adgang, ikke som „anden vej“
Mange virksomheder har brug for integration: data til BI, tilslutning til ERP/DMS/CRM, automatisering af import/export eller et kundeportal. Den typiske fejl er at bygge en REST-API „ved siden af“, som direkte læser tabeller, fordi det går hurtigt. Det skaber to sandheder: klientlogik og API-logik divergerer, og datakonsistens bliver tilfældig.
REST som facade foran stabile Use-Cases
En REST-API (HTTP-baseret grænseflade, oftest JSON) bør tilbyde faglige operationer, ikke spejle tabeller. Eksempler er: „Auftrag anlegen“, „Status abfragen“, „Dokument zu Vorgang hochladen“. API’en kalder de samme Use-Cases, som klienten også bruger. Dermed reducerer I doble regler og skaber klar governance: eksterne systemer får en kontrolleret adgang, der kan versionsstyres og sikres.
Sikkerhed og drift af en API
Set fra B2B-synspunkt er det ikke endepunkterne, men drift og sikring, der er vigtige:
- Autentificering: f.eks. token-baserede metoder; i virksomhedsmiljøer ofte tilkobling til centrale identiteter (SAML 2.0 er en udbredt standard for Single Sign-on).
- Autorisering: rettigheder pr. operation, ikke kun „må bruge API’en“.
- Ratebegrænsninger og beskyttelse mod misbrug: vigtigt ved partneradgange.
- Versionering: planlagte ændringer uden skjulte brud.
Hvis I allerede planlægger en grænseflade-modernisering, er det værd at se på en struktureret tilgang til eftermontering af en REST-API i eksisterende software: Det gør prioritering lettere og reducerer driftsrisici.
Deployment og opdaterbarhed: Den stille omkostningsdriver
Mange Delphi-systemer fejler ikke på funktionalitet, men på rollout-processerne. „Client-Server“ betyder i praksis: mange arbejdspladser, forskellige rettigheder, lejlighedsvis terminalservere eller Citrix, samt fjernkontorer med VPN. Et ordentligt system har en defineret update-proces.
Standardisere: konfiguration, versioner, miljøer
Typiske tiltag, der har umiddelbar effekt i driften:
- Træk konfigurationen ud af binærpakken: separate konfigurationsfiler eller centrale konfigurationskilder, så opdateringer ikke overskriver indstillingerne.
- Miljøprofiler: test, staging, produktion med klart adskilte database- og service-endepunkter.
- Automatiseret installation: reproducerbar, også til terminalserver-images.
Vigtigt: Selv når klienten „kun“ er et desktopprogram, har I fordel af release-disciplin som for servertjenester: versionsstyring med changelog, rollback-muligheder og definerede migrationsskridt.
Databasemigrationer: planlagt frem for risikabelt
Ved enhver strukturel ændring af tabeller, indekser eller views skal det være klart: hvilken version af applikationen forventer hvilket skema? En ordentlig tilgang benytter:
- Versionsstyrede migrationsskripter pr. release
- Bagudkompatible overgangsfaser, hvis client-rollout ikke kan ske samtidigt
- Veldefinerede backout-strategier (backup, gendannelse, definerede nedetidsvinduer)
Det er ikke et mål i sig selv: Uden denne disciplin bliver arkitekturforbedringer i det daglige „for farlige“ og ligger urørte.
Logging, Monitoring og fejlsøgning: Uden telemetri ingen stabilitet
„Det sker sjældent, men når det sker, står alt“ er et advarselstegn. Voksede Client-Server-systemer har ofte utilstrækkelig logging, især på tværs af systemgrænser. For driftsteams er det afgørende, at en fejltilstand kan rekonstrueres tidsmæssigt og fagligt.
Hvad der bør logges i praksis
- Korrelation: en operations-ID, der forbinder klient-, service- og databaseoperationer
- Kontext: bruger, tenant, maskine/placering, version, berørt operation
- Tekniske detaljer: databasefejlkoder, timeout-informationer, retry-forsøg
- Sikkerhedsrelevante hændelser: mislykkede logins, brud på rettigheder, mistænkelige opkaldsmønstre
Vigtigt er adskillelsen af tekniske logs og faglige protokoller. En faglig protokol (f.eks. „Bilag frigivet af bruger X“) er ofte auditrelevant; tekniske logs tjener til fejlanalyse og bør beskyttes og roteres tilsvarende.
Netværk, Security og rettigheder: Fra „kører på LAN“ til „kører i virksomheden“
Mange Delphi-klient-server-systemer blev designet i en tid, hvor „på LAN“ var lig med „betroet“. I dag gælder: segmentering, Zero-Trust-tilgange, VPN, MFA og restriktive firewall-regler er standard. Rydning af arkitekturen er derfor også Security-arbejde.
Database-rettigheder: princippet om mindste privilegier
En hyppig ældre tilstand er en databasebruger med omfattende rettigheder, som alle klienter bruger. Bedre er:
- Rollebaserede rettigheder pr. funktionsområde
- Adskilte adgangskonti for klient, services, batch-jobs
- Ingen admin-rettigheder i produktionsadgange til daglige operationer
Det begrænser fejlkonsekvenser og gør audits markant lettere. Samtidig øges transparens og diagnoseevne, fordi fejl i rettigheder ikke længere optræder „tilfældigt“.
Secrets og konfiguration: væk fra klartekst-adgangskoder
Adgangsoplysninger i INI-filer eller i registreringsdatabasen er en klassiker. Afhængigt af miljøet kan man anvende centrale Secret-Stores, krypteret konfiguration eller som minimum driftskoncept med restriktive filrettigheder. Afgørende er: Løsningen skal kunne administreres. Sikkerhed, der i daglig drift omgås, er ingen sikkerhed.
Trinvis modernisering: Hvor begynder man, når alt virker vigtigt?
Prioritering afgør, om rydningsarbejdet stopper efter to måneder eller giver målbar lettelse. En rækkefølge, der først adresserer driftssikkerhed og derefter trækker strukturforbedringer med, har vist sig effektiv.
En pragmatisk moderniseringskøreplan
- Stabilisere transaktions- og fejladfærd: mindre datakorruption, færre „manuelle reparationer“.
- Centraliseret dataadgang: ensartet forbindelseskonfiguration, timeouts, retries, logging.
- Saml use-cases: træk kritiske kerneoperationer ud af UI’en.
- Definér grænseflade udadtil: REST-API eller service-facade til integration, uden direkte adgang til tabellerne.
- Professionaliser deployment: reproducerbare opdateringer, versionerede DB-migrationer.
- Security-hærdning: rettigheder, secrets, netværksgrænser, auditmulighed.
Denne rækkefølge er ikke dogmatisk, men den sikrer, at tidlige skridt har umiddelbar effekt i driften, og at senere skridt bliver lettere.
Typiske faldgruber set fra projektet – og hvordan man undgår dem
Ved rydning fejler initiativer sjældent på teknik, men på randbetingelser. Nogle faldgruber optræder særligt hyppigt:
„Ved siden af“-ombygning uden kvalitetssikring
Når arkitekturtiltag kører parallelt med faglige ændringer, mangler der ofte et sikkerhedsnet. Mindst nødvendigt er: reproducerbare testdata, definerede smoke-tests for kerneprocesser og en release-proces, der ser rollback som et driftsværktøj og ikke som et nederlag.
To datamodeller samtidig
Den, der bygger nye moduler, men lader gamle skærmbilleder fortsat tilgå tabeller direkte, ender hurtigt med inkonsistente regler. Bedre: definer klare overgangsregler. Enten forbliver et område midlertidigt „gammelt“ og moderniseres ikke parallelt, eller det føres konsekvent gennem det nye lag.
Integration uden governance
Så snart partnere eller interne systemer tilsluttes, opstår der afhængigheder. Uden versionering, kontrakttests og en defineret deprecationsstrategi bliver enhver ændring en afstemningssløjfe. Det er mindre et udviklerproblem end et arkitektur- og driftsproblem.
Konklusion: Oprydning betyder at gøre drift og forandring håndterbare igen
Når I rydder op i klient-server-arkitekturer i Delphi, handler det ikke om «modernisering for moderniseringens skyld». Det handler om at strukturere en forretningskritisk digital virksomhedsløsning, så drift, sikkerhed og videreudvikling forbliver planbare. De mest effektive greb er ofte uspektakulære: klare lag, konsekvent dataadgang, rene transaktionsgrænser, robust logging og en grænsefladestrategi, der ikke duplikerer regler.
Det afgørende er fremgangsmåden: inkrementelt, med et målbillede og en prioritering, der først skaber stabilitet. På den måde kan I modernisere en voksende Delphi-landskab uden at sætte den daglige drift på spil – og uden at blive presset ind i en risikabel komplet nystart.
Hvis I ønsker at vurdere de næste skridt for jeres arkitektur, databaseadgange og grænseflader pragmatisk, så tal med os:
Im faglige felt spiller også Delphi Modernisierung en vigtig rolle, når integrationer, dataflows og videreudvikling skal fungere sammen på en kontrolleret måde.
Næste trin
Når emnet bliver til et reelt projekt, bør arkitektur, eksisterende systemer og drift tidligt vurderes samlet.
Vi støtter ikke kun ved enkeltspørsmål, men også når kildekodeudsnit, legacy-komponenter eller portalidéer skal udvikles til et robust virksomhedsprojekt.
- Eksisterende tilstand, målbillede og tekniske risici vurderes samlet.
- REST, dataadgang, portaler og udrulning bliver ikke udskudt som efterfølgende opgaver.
- De ser tidligt, hvilken vej der er økonomisk og driftsmæssigt bæredygtig.