From magazine topic to project implementation
Relevant service and technical pages for this post
Many companies face a similar situation today: an existing business application (often Delphi/VCL) implements central processes but suddenly must serve new channels. A customer portal needs data and operations, mobile users expect secure access, third-party systems (ERP, DMS, CRM, BI) require integrations. In this situation a REST API seems like the obvious step. In practice, however, API initiatives rarely fail because of HTTP or JSON — they fail because responsibility between client, server and data storage is unclear.
A viable REST-server architecture with Delphi is not created by laying “a few endpoints” over existing database tables. It emerges when the company jointly considers business rules, security requirements, data ownership, transaction boundaries and operational concepts. The REST server then becomes the stable contract layer between business logic and consumers: desktop client, portal, services, integration partners. This is where Delphi plays to its strengths: rapid development, robust runtime, high-performance native code, solid database integration (for example via BDE migration with native connectivity) and the ability to encapsulate business logic in libraries or server modules in a controlled way.
This article describes how companies plan REST-servers with Delphi so they remain consistent from a business perspective, fit into existing system landscapes, and do not become an operational liability. The focus is on architectural principles, typical pitfalls in modernization projects and concrete building blocks for security, data access, versioning and observability.
Why a REST API is an architecture decision in the enterprise
In a classic client-server world many rules were implicitly distributed in the desktop client: validations, state transitions, calculations, even authorization in some cases. As long as only one client existed that was manageable — technically messy but controllable. Once multiple consumers access the same business objects, the model breaks down:
- A portal cannot “reuse” client-side validations.
- Mobile apps should work offline but must not duplicate business rules.
- Integrations require stable, versioned contracts and clear error semantics.
- Compliance demands traceable access, role models and auditability.
The API becomes the place where business logic, rights and data access converge. Its architecture therefore determines whether your system remains extensible in the long term — or whether you are simply creating new technical debt.
Delphi as a platform for REST servers: strengths and typical use cases
Delphi is often associated with desktop applications in enterprises. For REST servers, however, Delphi is also well suited, especially when reusing existing business logic or delivering performant services. Typical use cases in B2B environments:
- API layer for legacy software: the existing Delphi business application remains as the UI; the REST server encapsulates data access and rules for new consumers.
- Backend for portal/customer area: a web portal consumes REST endpoints that use the same rule core as internal processes.
- Integration and interface server: ERP/DMS/CRM connectivity, import/export, event processing, scheduled jobs.
- Linux services or Windows services: long-running processes, queue workers, schedulers, document workflows.
What matters is less the framework label and more the discipline in layering, concurrency, error handling and deployment. Delphi supports both: fast iterations and at the same time clean, modular architecture — if planned deliberately.
Layer model: Layer-3 architecture as a basis for long-lived APIs
For enterprise software a clear, lean layering model has proven effective. In the Delphi context this is often described as Layer-3 architecture. Terminology varies, but responsibilities should be unambiguous:
1) API / transport layer (HTTP, serialization, routing)
This layer handles HTTP, protocol-level authentication, request/response formats, routing, status codes, content type, compression. No business rules belong here. Goal: interchangeability and testability. If you later extend a REST API with additional protocols (e.g. WebSocket, gRPC-like patterns, Server-Sent Events), the business core must remain stable.
2) Domain / service layer (business logic, use cases, rights, transactions)
The business truth lives here: state machines, calculations, plausibility checks, tenant rules, authorization checks on business actions. This layer should be UI-agnostic and, ideally, unaware of HTTP. Implement use cases such as “release order”, “close ticket”, “generate invoice” rather than just CRUD on tables.
3) Data access layer (repositories, SQL, FireDAC, mapping)
This layer encapsulates persistence: SQL, stored procedures, transaction control, locking strategies, connection pooling, DB-specific quirks. In Delphi the pragmatic choice is often BDE-Ablosung mit nativer Anbindung, especially for migrations (BDE replacement) and heterogeneous databases (SQL Server, PostgreSQL, MariaDB, Firebird). Crucially, the data access layer must not contain HTTP knowledge or make business decisions.
This model reduces coupling: changes to the data model do not force an API rewrite, and new clients automatically inherit the same logic. Especially in the Delphi modernization context, this is the foundation to decouple matured desktop applications step by step without interrupting operations.
API design for enterprise software: not CRUD but business contracts
Many APIs start with endpoints like /customers, /orders, /documents and implement CRUD. That can be sufficient for internal tools, but in enterprise software it quickly proves too shallow. Business processes consist of state transitions, rules, side effects and permissions.
Model resources, actions and states cleanly
A better pattern combines resources with explicit actions, for example:
- Read resource: GET /orders/{id}
- Trigger action: POST /orders/{id}/release
- Generate document: POST /orders/{id}/documents/invoice
- Check status: GET /orders/{id}/status
This makes it explicit in the API contract that “release” is not just a field update. The server can centrally implement validations, authorization, transactions, audit and side processes.
Error semantics and validation: make errors predictable for clients
Enterprise clients need to distinguish errors: validation errors (400), missing authorization (403), conflict due to concurrent modification (409), business rejection (often 409 or 422), temporary backend problems (503). A consistent error structure is important, e.g. error code, message, optional field hints and a correlation ID. This allows a portal to show user-friendly messages while support and operations can trace incidents efficiently.
Security: authentication is not authorization
In B2B contexts security rarely fails on encryption — it fails on missing separation of identity, roles and business authorization. A REST server architecture must therefore distinguish two levels:
Authentication (who is it?)
Common approaches are token-based mechanisms (e.g. JWT or opaque tokens), combined with TLS and a clear session strategy. Crucial aspects: token lifetime, refresh mechanism, revocation when roles change, and whether portals and internal systems use different identity providers. Delphi servers can act as resource servers and, depending on setup, as token issuers. In many enterprise landscapes integrating existing identity systems (e.g. AD/LDAP, SSO solutions) is a core requirement.
Authorization (is it allowed?)
Authorization belongs in the domain/service layer. Roles and permissions are rarely purely technical; they depend on tenant, location, organizational unit, contract status or process phase. Best practices:
- Role model (e.g. Admin, Case Worker, Auditor) as a basis
- Business policies (“may create invoice only in status X”, “may see only own tickets”)
- Multi-tenancy as a default: every request needs a tenant context
- Auditing: who executed which action and when
The API should not only return “access allowed/denied” but should prevent via server-side controls that parameter tricks expose data from other tenants. That sounds obvious, but in grown systems it is one of the most frequent architectural mistakes when teams move too fast to “tables over HTTP”.
Data access with FireDAC: transactions, pooling and database strategy
In enterprise applications data access is the stability factor: load spikes, deadlocks, long reports, concurrent updates, batch imports. FireDAC is a proven component in the Delphi ecosystem to serve various databases with a unified access layer. For a REST server architecture the following points are particularly important:
Transaction boundaries per use case
A REST API is typically request-based. That fits well with “one transaction per use case”: open a transaction within a request, perform business operations, then commit/rollback. Important: do not automatically wrap every endpoint in a transaction, but be consistent for write operations. Read endpoints may also require transactions depending on isolation levels and if consistent views are important.
Connection strategy and concurrency
Server concurrency means many simultaneous requests, each accessing the DB. Plan for:
- limited, monitored pool sizes
- timeouts for queries and connections
- clear rules for long-running operations (offload to jobs/workers)
A common mistake is running expensive reports or bulk exports synchronously on the same API instance that serves interactive portal requests. Better is to separate interactive from batch/async workloads.
Database modernization as part of API planning
If legacy data access still exists (e.g. BDE), the API becomes a catalyst: it forces clear data access boundaries. A controlled migration to FireDAC reduces risk and increases portability (PostgreSQL, MariaDB, SQL Server). Plan this not as a big-bang but incrementally: new server use cases adopt the new data access layer while legacy parts follow.
Versioning and backward compatibility: API contracts protect you
Enterprises often underestimate how costly breaking changes are. Once a customer portal, a partner system or a Windows service relies on your API you can’t “quickly” rename fields. A clean versioning strategy is therefore mandatory.
Pragmatic rules for versioning
- No breaking changes without a version: do not rename/remove fields or reinterpret endpoints.
- Extend rather than change: add new fields, mark old ones deprecated.
- Compatible defaults: avoid new mandatory fields or derive them server-side.
- Explicit versioning: e.g. /v1/… or via headers; consistency matters more than the method.
For Delphi teams this also means: keep DTOs (Data Transfer Objects) stable and design mapping deliberately instead of serializing domain objects 1:1. That increases initial effort but reduces long-term support costs.
Observability: plan logs, metrics and traces from the start
In production enterprise operation “works for me” is useless if faults cannot be reproduced. REST servers that serve many consumers require a minimum level of observability:
Structured logging with correlation ID
Every request should carry a correlation ID (accept one from upstream or generate one) and include it in logs. Log entries should be structured (e.g. JSON) so they can be ingested into central systems. At minimum include:
- request method, route, status code, duration
- user/tenant context (pseudonymized / policy-compliant)
- DB duration and error class
- correlation ID for support
Metrics for capacity and error trends
For scaling and stability you need metrics: requests per minute, p95/p99 latencies, error rates per endpoint, DB pool utilization, queue lengths. This does not have to be “cloud-native overkill”, but without numbers performance discussions become matters of opinion.
Error and exception handling as an architectural building block
Delphi exceptions must not leak uncontrolled to clients. A central exception middleware (or a global handler) should translate exceptions into consistent error responses, including a support ID and appropriate HTTP codes. Internally, stack traces belong in secure logs, not in client responses.
Synchronous vs asynchronous: move long-runners out of the REST response
Many enterprise processes are not “request/response in 200 ms”: PDF generation, data import, interface runs, reconciliations, mass updates, archiving. These workloads rarely belong in a synchronous REST endpoint because they tie up threads, cause timeouts and block users.
Job pattern
A proven approach is: an endpoint starts a job and the server immediately returns a job ID. A separate endpoint provides status/result. Optionally a callback/webhook notifies completion. In Delphi this can be implemented with worker services, a job table and a clear state machine. Benefit: stability and predictable scaling.
Queues and services
Depending on the environment a message queue may be useful — but it is not always required. The important principle is: interactive APIs remain responsive; batch processes run controlled, repeatable and observable — as Windows services or Linux services depending on deployment.
Deployment in the enterprise: Windows, Linux, containers, on-prem
A REST server architecture is only “complete” when it is operable. Enterprises differ widely: classic Windows servers, virtualized Linux hosts, container platforms, strict network zones, proxy and certificate requirements. Delphi is flexible here if dependencies are controlled cleanly.
Configuration and secrets
Configuration must be environment-specific (Dev/Test/Prod). Credentials do not belong in binaries or repositories. Use secure storage (e.g. the platform’s secrets management) and separate configuration values from code releases. Also plan rotations (DB passwords, API keys) without rebuilding the system.
Release and rollback strategies
When multiple consumers rely on an API you need controlled releases: migration scripts for DB changes, feature toggles for gradual activation, clear rollback procedures. In particular, database changes must remain backward compatible if a server version rollback must be possible.
Integration with legacy software: iterative modernization instead of big bang
In many Delphi landscapes the business core is valuable but technically “glued together”: UI-centric data access, global state, mixed responsibilities. A REST API can be both a risk and an opportunity. The goal should be a path that delivers measurable improvements with reasonable effort.
Strangler pattern for APIs
Instead of rebuilding everything, define business boundaries that deliver real value: e.g. “order status and documents for the customer portal”, “master data lookup for mobile users”, “interface for ERP bookings”. Implement these use cases as new API functions including domain layer and data access. The legacy client can gradually switch to the same server use cases without the UI needing an immediate rebuild.
Shared business logic: useful but controlled
Delphi allows business libraries to be used both in the server and in existing applications. That can be a bridge, but it carries risks: if UI dependencies leak into shared logic you lose decoupling. A clear rule helps: shared logic may only contain non-UI code, no global state, clear interfaces and testable units. Everything else remains separated.
Typical mistakes in REST server projects — and how to avoid them
“We’ll just publish tables”
If endpoints mirror tables directly you end up with an unstable system: every DB refactor becomes an API-breaking change, business rules are duplicated in clients, and security holes via unchecked parameters become more likely. Better: domain use cases and DTOs that stabilize the contract.
Business authorization only in the client
Clients are replaceable and can be manipulated. Authorization belongs on the server and must enforce business rules, not only technical roles.
No clear strategy for concurrency
Concurrent updates will occur: two case workers, portal and internal client, or an import job. Without optimistic locking (e.g. RowVersion/Timestamp), conflict codes (409) and clear merge rules you get data loss or “last write wins” errors.
Long-runners block interactive endpoints
Synchronous PDF generation or exports cause timeouts and “hang” experiences. The job pattern with status endpoints is better.
Observability added as an afterthought
Without correlation ID, structured logs and metrics every incident becomes a search operation. Observability is not a luxury but an operational prerequisite.
Concrete checklist for your REST server architecture with Delphi
- Separate layers clearly: transport (HTTP), domain (use cases), data access (FireDAC/SQL).
- Treat the API as a contract: keep DTOs stable, plan versioning, avoid breaking changes.
- Two-level security: authentication (tokens) plus authorization (business policies, tenant).
- Set transactions deliberately: per use case, with timeouts and conflict strategy.
- Make long-runners asynchronous: jobs/workers, Windows or Linux services.
- Build observability in: correlation ID, structured logs, metrics, central error handling.
- Plan deployment realistically: configuration/secrets, rollback, database migrations.
- Modernize iteratively: valuable use cases first, decouple legacy parts step by step.
Conclusion: REST servers deliver value only as operational and domain architecture
A REST server architecture with Delphi is particularly effective for enterprises when it is not understood as a “technical surface” but as the connecting core between processes, data and channels. Key factors are clean layers (Layer-3 architecture), business-modeled endpoints, consistent security and tenant logic, and an operational model with versioning, monitoring and controlled concurrency. That turns the API into a stable platform: for portals, integrations, services and the incremental Delphi modernization — without risking the business substance of a mature system.
If you would like to evaluate how a robust REST API can be implemented on your existing Delphi landscape (including database strategy, FireDAC, services and operations), reach us here: https://net-base-software-gmbh.de/kontakt/
Next step
When the topic becomes an actual project, architecture, existing systems and operations should be considered together from the outset.
We support not only with individual issues, but also when source snippets, legacy topics, or portal ideas are to be turned into a robust enterprise project.
- Current state, target state and technical risks are assessed jointly.
- REST, data access, portals and rollout are not deferred to a later stage as secondary consequences.
- You can see early on which path is economically and operationally viable.