Den som ønsker å rydde opp i klient‑server‑arkitekturer i Delphi, står sjelden overfor et «dårlig» system. Ofte er det snakk om robust forretningsprogramvare som er utvidet over år, håndterer mange unntakstilfeller og fungerer pålitelig i det daglige. Problemet skyldes ikke Delphi som plattform, men opparbeidede ansvarsområder: Klienten inneholder plutselig datalogikk, «serveren» er i realiteten bare en database, og grensesnitt har blitt lagt til ad hoc. Det slår tilbake når nye sikkerhetskrav, databasebytter, hjemmekontor‑VPN, terminalserver‑oppsett eller integrasjoner med ERP, DMS eller portaler kommer til.
Denne artikkelen viser hvordan du kan strukturert rydde opp i Delphi‑klient‑server‑landskap i praksis: uten dogmatisk totalombygging, men med klare mål for drift, administrasjon, datakonsistens, integrasjonsevne og vedlikeholdbarhet. Fokus ligger på beslutninger som IT‑ledelse og tekniske prosjektansvarlige kan styre: arkitekturgrenser, rollout‑strategier, logging, rettighetskonsepter, migrasjonsveier og typiske risikokilder.
Hvordan man kjenner igjen at klient‑server‑arkitekturen er „sammenvokst“
Teknisk gjeld viser seg i drift ofte tidligere enn i kildekoden. Typiske signaler er mindre «dårlig kode» og mer gjentakende friksjonspunkter mellom klient, database og infrastruktur:
- Uklare ansvarsforhold: Klienten «vet» for mye om tabeller, triggere, lagrede prosedyrer eller til og med filstier på Shares.
- Vanskelige releaser: Hver lille endring krever klientutrulling på mange arbeidsplasser, ofte med manuelle trinn.
- Skjøre datatilganger: Tilfeldige deadlocks, inkonsistente transaksjoner eller «hengende» låser i toppbelastning.
- Sikkerhet som ettertanke: Databaseadgang skjer med for brede rettigheter; passord ligger i INI‑filer; nettverkssegmentering bryter funksjoner.
- Integrasjon er uforholdsmessig kostbar: Et Kundenportal eller en REST‑API er vanskelig å ettermontere, fordi forretningsregler er distribuert.
- Vanskelig feilsøking: Uten pålitelig logging er det uklart om feil oppstår i klienten, i nettverket, i databasen eller i et grensesnitt.
Hvis flere av disse punktene stemmer, er «opprydding» ikke kosmetikk, men et tiltak for driftssikkerhet. Målet er ikke perfeksjon, men et system som pålitelig kan endres.
Klient‑server i Delphi: Hva som virkelig teller i drift
I mange Delphi‑landskap blir «klient‑server» implisitt forstått som «klienten kommuniserer direkte med databasen». Det kan fungere — så lenge rammebetingelsene ikke endres. For virksomheter er imidlertid andre egenskaper viktigere:
- Skalerbarhet i hverdagen: ikke prangende benchmarks, men stabil ytelse ved typiske lasttopper (månedsslutt, skiftbytte, importkjøringer).
- Endrebarhet: Tilpasninger uten kjedereaksjon av utrulling, datamigrasjon og opplæring.
- Sikker drift: etterprøvbare tilgangsrettigheter, revisjonssporbarhet, sikker håndtering av hemmeligheter (Credentials), nettverksgrenser.
- Integrasjonsevne: definerte grensesnitt i stedet for en «annen klient» som også kobler seg direkte mot tabellene.
Disse målene lar seg nå uten å «erstatte» Delphi. Avgjørende er hvordan dere trekker grenser: Hva er UI, hva er forretningslogikk, hva er dataadgang, og gjennom hvilke grensesnitt kan andre systemer kobles til?
Rydde opp i klient‑server-arkitekturene i Delphi: Målbilde i stedet for Big Bang
Et praktisk målbildet er sjelden et radikalt brudd. Et inkrementelt forløp med en tydelig arkitektur-ramme har vist seg å fungere. Ofte realiseres dette som en Layer-3-arkitektur: tre lag med klare ansvarsområder. „Layer“ betyr her: en definert separasjon mellom UI (presentasjon), forretningslogikk (regler/brukstilfeller) og dataadgang (SQL, transaksjoner, persistens). Dette kan struktureres også innenfor en Delphi-monolitt før dere trekker ut en faktisk tjeneste.
Trinn 1: Gjør arkitekturgrensene synlige
Før dere endrer struktur, må dere vite hvor kobling oppstår. Typiske grensebrudd i Delphi-klienter er:
- UI-hendelser (knappeklikk) inneholder SQL eller direkte tabelltilgang.
- Forretningsregler er distribuert: delvis i klienten, delvis i triggere, delvis i rapporter eller importskripter.
- Databaseforbindelser åpnes «ved siden av» overalt, med ulike parametere.
Målet er en oversiktlig kjerne: få inngangspunkter til forretningsfunksjoner og en sentral dataadgang som håndterer forbindelser, transaksjoner og feilhåndtering konsekvent.
Trinn 2: Definer «kontrakter» – også uten tjenester
Mange team tror at grensesnitt først oppstår med REST. I virkeligheten trenger dere først interne kontrakter: Hvilke funksjoner finnes, hvilke parametere overføres, hvilke feilkoder er tillatt, hvilke transaksjoner hører sammen? Disse kontraktene kan først eksistere som klart definerte moduler/byggesteiner i Delphi-prosjektet. Senere kan de relativt ryddig overføres til en REST-server eller til en Windows- henholdsvis Windows- og Linux-tjenester.
Stabilisere dataadgang: FireDAC, transaksjoner og en klar tilkoblingsstrategi
Dataadgang er i klient‑server-oppsett ofte det viktigste grepet for stabilitet. To tema dominerer: konsistente tilkoblinger og klare transaksjonsgrenser. I Delphi-miljøer er BDE-avløsning med native tilkoblinger (dataadgangsbibliotek med drivere og tilkoblingspooling) ofte moderniseringsankeret, spesielt hvis BDE (Borland Database Engine, et eldre dataadgangslag) fortsatt er i bruk.
BDE-avløsning: Mer enn et driverbytte
En BDE-avløsning undervurderes hvis man ser den som en «bytte av komponenter». I praksis berører den:
- SQL-dialekt og parameterisering: Ulike databaser og drivere reagerer forskjellig på datoformater, NULL-håndtering, sortering og tegnsett.
- Transaksjonsatferd: Autocommit, isolasjonsnivåer (regler for hvor strengt låsing/lesing håndteres) og feilgjenoppretting.
- Ytelse og låsing: Enkel eldre logikk stoler ubevisst på implisitte låsemekanismer.
Operativt viktig er et testkonsept som ikke bare klikker seg gjennom skjermbilder, men som gjenskaper typiske bokførings- og importforløp under belastning.
Transaksjoner: Mindre magi, flere regler
I mange etablerte Delphi-klienter oppstår transaksjoner tilfeldig: Et skjema lagrer flere tabeller, men feilsituasjoner rulles ikke ryddig tilbake. Det fører til deltilstander som senere må «manuelt ryddes opp». Bedre er et konsekvent mønster:
- Transaksjon per faglig operasjon (f.eks. «Opprett ordre», «Bokfør varemottak»), ikke per SQL-setning.
- Tydelige feilforløp: Ved valideringsfeil ingen halvferdig datatilstand, men kontrollert avbrudd.
- Idempotens ved importer: Gjentakbar innspilling uten dobbel bokføring.
For IT-drift og support er det særlig viktig: Når en operasjon feiler, må den feile etterprøvbart — med logginnføringer, korrelerbare IDer og en entydig feilmeldingsklasse (f.eks. autorisering, datakonflikt, teknisk feil).
Flytte forretningslogikk ut av klienten — uten å ødelegge brukervennligheten
Mange Delphi-klienter er historisk vokst «UI-sentrert»: Prosessen ligger i skjemaer, valideringer i OnChange-Events, sideeffekter i OnExit. Dette er fra brukerens synspunkt ofte raskt og direkte — men fra arkitekturperspektiv vanskelig å teste og utvide.
Use-cases i stedet for formulærlogikk
Et praktisk mellomsteg er å samle funksjonaliteten i faglige use-cases: En use-case kapsler en operasjon (f.eks. «frigjøre faktura») inkludert valideringer, beregninger, dataadgang og protokollføring. UI-en kaller den og viser resultater i stedet for å implementere reglene selv. Fordel: Senere kan den samme use-casen benyttes via en REST-API, for eksempel for en portal eller en importtjeneste.
Sentraliser regler: Validering, nummerrekker, tilstandsmodeller
Typiske kandidater for sentralisering er:
- Valideringsregler (påkrevde felt, verdiområder, plausibilitetskontroller)
- Nummerrekker (bilag, batcher, operasjoner) med konfliktforebygging
- Tilstandsmodeller (utkast → kontrollert → frigitt → bokført) med tillatte overganger
- Autorisasjonskontroller nær forretningsoperasjonen, ikke bare i UI-en
Spesielt for autorisasjoner er dette avgjørende: Hvis reglene bare ligger i klienten, er de vanskelige å holde konsistente for grensesnitt, automatiseringer eller senere portaler.
Bli grensesnittvennlig: REST-API som kontrollert tilgang, ikke som «andre vei»
Mange virksomheter trenger integrasjon: data til BI, tilkobling til ERP/DMS/CRM, automatisering av import/eksport eller en kundeportal. Den typiske feilen er å bygge en REST-API «ved siden av» som går direkte på tabellene fordi det går raskt. Det skaper to sannheter: klientlogikk og API-logikk divergerer, og datakonsistens blir tilfeldig.
REST som fasade foran stabile use-cases
En REST-API (HTTP-basert grensesnitt, vanligvis JSON) bør tilby faglige operasjoner, ikke speile tabeller. Eksempler er: «Opprett ordre», «hent status», «last opp dokument til hendelse». API-en kaller de samme use-casene som klienten bruker. På den måten reduserer man doble regler og etablerer klar styring: eksterne systemer får en kontrollert tilgang som kan versjoneres og sikres.
Sikkerhet og drift av en API
Fra et B2B-perspektiv er det mindre endepunktene som er interessante, og mer drift og sikring:
- Autentisering: f.eks. tokenbaserte metoder; i bedriftsmiljøer ofte integrasjon mot sentrale identiteter (SAML 2.0 er en utbredt standard for Single Sign-on).
- Autorisering: Rettigheter per operasjon, ikke bare «kan bruke API».
- Rate-limits og beskyttelse mot misbruk: viktig ved partnertilganger.
- Versjonering: planlagte endringer uten stille brudd.
Hvis dere allerede planlegger en modernisering av grensesnitt, er det verdt å se på en strukturert tilnærming for å ettermontere en REST-API i eksisterende programvare: Dette forenkler prioritering og reduserer driftsrisiko.
Deployment og oppdaterbarhet: Den skjulte kostnadsdriveren
Mange Delphi-systemer feiler ikke på funksjonalitet, men på utrullingsprosessene. «Client-Server» betyr i praksis: mange arbeidsstasjoner, varierende rettigheter, av og til terminalservere eller Citrix, i tillegg eksterne lokasjoner med VPN. Et ryddig system har en definert oppdateringsprosess.
Standardisere: Konfigurasjon, versjoner, miljøer
Typiske tiltak som har umiddelbar effekt i drift:
- Hente konfigurasjon fra binærpakken: separate konfigurasjonsfiler eller sentrale konfigurasjonskilder, slik at oppdateringer ikke overskriver innstillinger.
- Miljøprofiler: Test, staging, produksjon med klart adskilte database- og tjenesteendepunkter.
- Automatisert installasjon: reproduserbar, også for terminalserver-images.
Viktig: Selv om klienten «kun» er et skrivebordsprogram, vil dere ha nytte av releasedisiplin som for servertjenester: versjonering med changelog, rollback-alternativer og definerte migreringstrinn.
Databasemigrasjoner: planlagt fremfor risikabelt
Ved enhver strukturell endring av tabeller, indekser eller views må det være klart: Hvilken versjon av applikasjonen forventer hvilket skjema? En ryddig tilnærming benytter:
- Versjonerte migrasjonsskript per release
- Tilbakekompatible overgangsfaser, når klientutrulling ikke kan gjennomføres samtidig
- Tydelige backout-strategier (backup, gjenoppretting, definerte nedetidsvinduer)
Dette er ikke et mål i seg selv: Uten denne disiplinen blir arkitekturforbedringer i det daglige «for farlige» og blir liggende.
Logging, overvåking og feilsøking: Uten telemetri ingen stabilitet
«Det skjer sjelden, men når det skjer, står alt» er et varseltegn. Etablerte client-server-systemer har ofte utilstrekkelig logging, spesielt på tvers av systemgrenser. For driftsteam er det avgjørende at en feilsituasjon kan rekonstrueres tidsmessig og faglig.
Hva som bør logges i praksis
- Korrelasjon: en korrelasjons-ID som knytter klient, tjeneste og databaseoperasjoner
- Kontekst: bruker, tenant, maskin/sted, versjon, berørt operasjon
- Tekniske detaljer: database-feilkoder, timeout-informasjon, gjenforsøk
- Sikkerhetsrelevant: mislykkede innlogginger, brudd på rettigheter, mistenkelige anropsmønstre
Viktig er separasjonen mellom tekniske logger og faglige protokoller. En faglig protokoll (f.eks. «Beleg freigegeben durch Benutzer X») er ofte revisjonsrelevant; tekniske logger brukes til feilanalyse og bør beskyttes og roteres deretter.
Nettverk, sikkerhet og rettigheter: Fra «kjører i LAN» til «kjører i bedriften»
Mange Delphi-klient-server-systemer ble designet i tider hvor «i LAN» var likestilt med «pålitelig». I dag gjelder: segmentering, Zero-Trust-tilnærminger, VPN, MFA og restriktive brannmurregler som standard. Å rydde opp i arkitekturen er dermed også sikkerhetsarbeid.
Databasetillatelser: prinsippet om minste privilegium
En vanlig arvtilstand er en databasebruker med omfattende rettigheter som alle klienter bruker. Bedre er:
- Rollebaserte rettigheter per funksjonsområde
- Separate tilganger for klient, tjenester, batch-jobber
- Ingen administrative rettigheter i produksjonsadgang for daglige operasjoner
Det begrenser konsekvensene av feil og gjør revisjoner betydelig enklere. Samtidig øker transparens og diagnoseevne, fordi rettighetsfeil ikke lenger oppstår «tilfeldig».
Hemmeligheter og konfigurasjon: bort fra klartekstpassord
Legitimasjon i INI-filer eller i registeret er en klassiker. Avhengig av miljø kan sentrale Secret-Stores, kryptert konfigurasjon eller minst driftskonsepter med restriktive filrettigheter være aktuelle. Avgjørende er: løsningen må forbli administrerbar. Sikkerhet som omgås i hverdagen, er ingen sikkerhet.
Trinnvis modernisering: Hvor begynne når alt virker viktig?
Prioriteringen avgjør om oppryddingen stopper etter to måneder eller gir målbart lettelse. En rekkefølge som først adresserer driftssikkerhet og deretter fører med seg strukturforbedringer, har vist seg å fungere.
En pragmatisk moderniseringsplan
- Stabilisere transaksjons- og feilhåndtering: mindre datakorruptjon, færre «manuelle reparasjoner».
- Sentralisert datatilgang: enhetlig tilkoblingskonfigurasjon, timeouts, gjenforsøk, logging.
- Samle use-cases: trekke kritiske kjerneoperasjoner ut av UI-en.
- Definere grensesnitt utad: REST-API eller servicefasade for integrasjon, uten direkte tilgang til tabeller.
- Profesjonalisere utrulling: reproduserbare oppdateringer, versjonerte database-migrasjoner.
- Sikkerhets-hardening: rettigheter, secrets, nettverksgrenser, revisjonsevne.
Denne rekkefølgen er ikke dogmatisk, men den sørger for at tidlige tiltak gir umiddelbar effekt i drift og gjør senere steg lettere.
Typiske fallgruver fra prosjektperspektiv – og hvordan man unngår dem
Ved opprydding mislykkes tiltak sjelden på grunn av teknologi, men på grunn av rammebetingelser. Noen fallgruver oppstår spesielt ofte:
«Ved siden av»-ombygging uten kvalitetsnett
Når arkitekturtiltak kjøres parallelt med fagendringer, mangler det ofte et sikkerhetsnett. Minst nødvendig er: reproduserbare testdata, definerte smoke-tester for kjerneprosesser, og en release-prosess som ser rollback ikke som et nederlag, men som et driftsverktøy.
To datamodeller samtidig
Den som bygger nye moduler, men lar gamle skjemaer fortsette å aksessere tabeller direkte, får raskt inkonsistente regler. Bedre: definer klare overgangsregler. Enten beholdes et område midlertidig «gammelt» og moderniseres ikke parallelt, eller så styres det konsekvent via det nye laget.
Integrasjon uten styring
Så snart partnere eller interne systemer kobles til, oppstår avhengigheter. Uten versjonering, kontraktstester og en definert utfasingstrategi blir enhver endring en avstemmingssløyfe. Det er mindre et utviklerproblem enn et arkitektur- og driftsproblem.
Konklusjon: Å rydde opp betyr å gjøre drift og endring håndterbare igjen
Når dere rydder opp i klient-server-arkitekturen i Delphi, handler det ikke om «modernisering for moderniseringens skyld». Det handler om å strukturere en forretningskritisk digital bedriftsløsning slik at drift, sikkerhet og videreutvikling forblir planlagte. De mest effektive grepene er som regel uspektakulære: klare lag, konsistent dataaksess, tydelige transaksjonsgrenser, robust logging og en grensesnittstrategi som ikke dupliserer regler.
Det avgjørende er fremgangsmåten: inkrementelt, med et målbilde og en prioritering som først skaper stabilitet. Slik kan dere modernisere en opparbeidet Delphi-landskap uten å sette daglig drift i fare – og uten å bli presset inn i en risikabel fullstendig nystart.
Hvis dere ønsker å vurdere de neste stegene for arkitekturen, databaseaksessene og grensesnittene på en pragmatisk måte, ta kontakt med oss:
I faglig sammenheng spiller også Delphi modernisering en viktig rolle når integrasjoner, dataflyter og videreutvikling må spille sammen på en ryddig måte.
Diskuter prosjekt eller moderniseringsprosjekt med Net-Base.