From magazine topic to project implementation
Relevant service and technical pages for this post
Video-Botschaft
Developing REST Servers with Delphi: Architecture, Security and Operations in Practice
Kurz erklärt, warum bei Delphi-REST-Servern nicht der erste funktionierende Endpunkt zählt, sondern Architektur, Security und Betrieb: konsistente Fehler, Authentifizierung, Logging/Monitoring und sauberes Deployment für Windows und Linux.
Video mit KI erstellt
Transkript anzeigen
Hallo, ich bin Mark. Der erste funktionierende REST-Endpunkt ist oft der Anfang der Probleme, nicht das Ende.
Im Beitrag „REST-Server mit Delphi entwickeln: Architektur, Sicherheit und Betrieb in der Praxis“ geht es genau darum. In Unternehmen scheitern APIs selten an Delphi oder am Framework.
Sie scheitern an Betrieb: uneinheitliche Fehler, fehlende Zeitlimits, unklare Zuständigkeiten. Und an Sicherheit: Authentifizierung, also wer sich ausweist, und Autorisierung, also was jemand darf.
Wichtig ist eine klare Trennung: vorne HTTP und Validierung, in der Mitte die Fachlogik, hinten Datenzugriff. Dazu gehören Logging und Monitoring, damit Sie Störungen nachvollziehen, bevor Nutzer Tickets schreiben.
Wenn Sie dazu Fragen haben, klären wir gern die typischen Stolperstellen aus der Praxis.
Anyone who wants to develop a REST-server with Delphi rarely pursues that goal for its own sake within an enterprise. Typically it is about reliable interfaces between mature systems, portals, services and databases — with clear requirements for operation, security and maintainability. The decisive factor is not how fast a first endpoint responds, but whether the service remains stable in day-to-day use: reproducible error patterns, controlled data access, clean authentication, well-defined architectural responsibilities and a deployment that fits Windows and Linux environments.
Delphi is pragmatic in many organisations: existing business logic can continue to be used, performance is usually sufficient, and there are multiple ways to implement HTTP-based APIs. In practice the options differ less in “can REST” than in transparency and operations: how consistently can logging, timeouts, reverse-proxy rules, versioning, OpenAPI documentation and security mechanisms be implemented?
This article classifies the main Delphi approaches and shows what IT leadership, administrators and technical project owners should pay attention to: from API design through security and BDE replacement with native binding-data access to observability (logs, metrics, tracing) and deployment as Windows or Windows- and Linux-services. The goal is a robust foundation for integrations with ERP, DMS, CRM or customer portals — without putting framework internals at the centre.
When a REST server in Delphi is particularly worthwhile
A Delphi-REST backend is often sensible when Delphi is already established in the company or when business logic and data access from legacy applications should be reused. Typical B2B scenarios:
- Making legacy software API-capable: A VCL application or a client-server core receives a REST layer so that portals, external systems or internal services can access it in a standardized way.
- Integration and decoupling: Multiple consumers (desktop, web portal, batch, partner) should use the same business processes without direct database access or file interfaces.
- Phased modernization: First introduce a stable API, then gradually rebuild UI, modules or database. The API becomes a controlled boundary and reduces side effects.
- Operation and security: HTTP APIs can be run conveniently behind reverse proxies, centrally authenticated and integrated into monitoring stacks.
Expectation management is important: REST is an integration interface, not a replacement for domain consistency. Those who start without a clear domain model, defined transaction boundaries or unambiguous data ownership quickly build an API that is reachable but expensive to maintain and support in the long run.
REST servers with Delphi: options at a glance
Delphi offers several paths to an REST service. For decision-makers the question is less “which is modern” and more: how well does it fit team structure, operating model, expected lifespan and compliance requirements?
Delphi WebBroker: lean, transparent, well controllable
WebBroker is an established Delphi framework for HTTP applications. It is close to the protocol (request/response), therefore easy to understand and attractive for many B2B scenarios where controlled error handling, clean header handling and a manageable stack are important. WebBroker can typically be operated well behind a reverse proxy that terminates TLS and enforces central security rules.
Practical consequence: many convenience features (routing conventions, middleware chains, OpenAPI maintenance) need to be added in a structured way. That is not a disadvantage when architectural standards are already a priority.
Delphi Horse: routing and middleware for clear API standards
Delphi Horse is lightweight and focuses on understandable routing plus a middleware principle. Middleware here means reusable processing steps “around” the endpoint, such as authentication, logging, rate limits or request validation. This is a productive approach for many teams because it allows standards to be enforced centrally.
Important for operations: define a uniform error format, timeouts, maximum request sizes and a logging standard early. Without these guidelines the system remains functional but becomes unnecessarily complex to support and extend.
RAD Server: platform approach with integrated building blocks
RAD Server (formerly EMS) follows more of a platform approach with integrated functions like user management and other components. That can fit scenarios where multiple clients need a common backend and the platform features are intentionally used. For pure integration APIs it is not automatically the best choice; there transparency, low dependencies and a lean operating model often matter more.
DataSnap: realistically assess existing installations
DataSnap is historically present in many Delphi landscapes and can provide HTTP/REST-like endpoints. For new initiatives, however, one should check whether it fits the planned API style, authentication (e.g. JWT), OpenAPI/Swagger and modern operational requirements. A pragmatic path is common: continue to use existing logic, but expose a clearly defined REST API layer that enforces standards for security, logging and versioning.
Architecture that supports operation and maintenance
A common mistake in REST projects is “the handler does everything”: HTTP parameters are read, SQL is built directly, business rules are implemented and logging is added on the side. That may be quick at first but leads to hard-to-test code and unstable changes.
In enterprise environments a clear layering proves effective. A common, pragmatic structure is a Layer-3 architecture (three layers) that separates responsibilities:
Transport layer: HTTP, auth, validation, response format
This layer accepts the request, performs basic validation and produces a consistent response format. Authentication and authorization (who may do what) belong here, as do technical rules like request limits, CORS and assignment of correlation IDs (unique IDs per request for tracing).
Domain layer: business use-cases instead of endpoint logic
The domain encapsulates business processes like “create order”, “change status” or “link document”. Crucial: this logic should be as independent of the HTTP framework as possible. Then the same domain can be used by a Windows- and Linux-services, a Linux daemon or a batch process without duplicating logic.
Persistence and integration: FireDAC, database, ERP/DMS/SMTP
This layer consolidates access to databases and external systems. For Delphi the usual data access stack to connect PostgreSQL, SQL Server, MariaDB/MySQL or Firebird cleanly is BDE-Ablosung mit nativer Anbindung. What matters is not only “use FireDAC” but binding rules: connection handling, transaction boundaries, timeouts, parameter binding, translation of technical errors into API error codes and consistent retry strategies where they make sense for the business.
API design: stable over years, not just until go-live
In B2B environments an API is a long-lived maintained interface. The decisive term is compatibility: consumers rely on fields, status codes and semantics. The clearer you define these rules, the less effort results in integration, support and releases.
Resources and paths: consistency over creativity
Stable APIs are typically resource-oriented: “/customers”, “/orders/123”, “/orders/123/items”. Process actions can be modelled as sub-resources or clearly justified action endpoints, e.g. “/orders/123/cancel”, when a pure CRUD model does not fit the domain. The key is a uniform convention that is documented and used across the team.
HTTP methods and status codes: clear signals for consumers
An API is easier to integrate when it uses expected HTTP semantics: GET for reads, POST for creation, PUT/PATCH for updates, DELETE for deletions. Equally important is consistent error behaviour. Helpful for operations is a standardized error object containing:
- HTTP status (e.g. 400, 401, 403, 404, 409, 422, 500)
- stable error code (machine-readable, documented)
- correlation ID (for quick mapping in logs)
- optional details (e.g. field errors for validation)
A common pitfall is returning “200 OK” with an error message in the body. That complicates integrations and leads to error-prone client logic.
Versioning and compatible extension
Versioning is a process and communication problem, not just a technical one. Common approaches are URL versioning (e.g. “/api/v1”) or header versioning. In many organisations the main principle is: extend compatibly. Adding new fields is usually uncritical. Removing or reinterpreting fields requires a new version and a clearly communicated migration window. That reduces integration breakages and makes releases plannable.
Security: authentication, authorization, attack surface
An REST service is a potential entry point. Many security issues do not arise from missing encryption but from detail errors: overly broad permissions, tokens that are valid too long, unprotected admin endpoints, uncontrolled CORS rules or logs containing sensitive data.
TLS and reverse proxy: clear responsibilities in the network
In typical setups TLS terminates at the reverse proxy (e.g. Nginx, Apache or Microsoft IIS as a reverse proxy). The Delphi service runs internally on HTTP and is only reachable from the internal network. Important are clean rules for “X-Forwarded-For” and “X-Forwarded-Proto” so that client IP and protocol are interpreted correctly. These pieces of information are relevant for audit, rate limiting and troubleshooting.
JWT, API keys and SSO: what fits in practice
For system-to-system integrations API keys or client credentials mechanisms are common. For user access in enterprise contexts JWT (JSON Web Tokens) combined with a central identity provider (e.g. OIDC) are often practical. In SSO landscapes SAML 2.0 can also be relevant (a standard for single sign-on, typically between portal/gateway and identity provider).
Regardless of the method, define:
- Key and certificate rotation (how are signatures renewed?)
- Roles/scopes (which permissions apply to which endpoints?)
- Multi-tenancy (how is tenant assignment enforced cleanly?)
- Audit logging (who triggered which business action and when?)
Input validation, CORS and rate limiting
Input validation should be multi-stage: syntactic (data types, JSON structure), domain-specific (value ranges, state transitions) and security-relevant (filenames, paths, headers). For browser clients CORS matters (rules which origins and headers are allowed). CORS should be configured restrictively. Rate limiting protects against abuse and load spikes; it is often implemented at the reverse proxy and supplemented by server-side limits (maximum body size, timeouts, limited parallelism).
FireDAC and database access: stability comes from rules
In REST backends database access is often the dominant factor for latency and stability. FireDAC provides the technical means, but operational safety arises from guardrails.
Connection handling and concurrency
A classic mistake is a globally shared database connection that is used concurrently by multiple requests. In a REST-server with parallel processing (threads/workers) it must be clear which objects are thread-safe and which are not. Practically this means: manage connections and query objects cleanly per request or per unit of work, or use controlled pooling depending on the server model. This reduces deadlocks, sporadic errors and hard-to-reproduce issues.
Transactions along use-cases
Transactions belong in the domain: a use-case decides what belongs atomically together. Often “one request = one transaction” is sensible, but not always. Read-only endpoints often do not require an explicit transaction, while write flows must modify multiple tables consistently. For external integrations (ERP, DMS, webhooks) distributed transactions are usually unrealistic; here clear sequencing and compensating logic help (how can a partial success be cleaned up?).
Timeouts, backpressure and controlled failure
Without timeouts requests, threads and DB connections pile up. Therefore set timeouts at both the HTTP and DB level. Complementary backpressure is important: limit parallelism and queue lengths so the system can respond predictably with 503 (Service Unavailable) under load instead of failing due to resource exhaustion. For operations a fast, clear failure mode is better than minute-long hangs.
Payloads, DTOs and long-term compatibility
JSON is the standard, but interoperability is determined by details: date/time format, time zones, null values, decimal representation, field names and encoding. Define a standard (e.g. ISO-8601 in UTC) and apply it consistently.
Publish DTOs instead of database structures
DTOs (Data Transfer Objects) are API data models optimized for exchange. They should not simply mirror database tables. This prevents internal schema changes from immediately becoming API breaks. In addition, DTOs let you control which internal fields do not leave the system (e.g. flags, audit columns) and how you can refactor internally later without endangering integrations.
Consider idempotency and retries
Timeouts and retries are normal in enterprise networks. Define which operations are idempotent (multiple executions yield the same result) and how duplicate POSTs can be avoided, for example via an idempotency key for certain write operations. This reduces duplicates, inconsistent states and support cases.
Documentation and tests: OpenAPI as a common working basis
An API in B2B is rarely used by a single team. OpenAPI (Swagger) is a practical common language because specifications are automatable: client generation, mocking, contract tests and diffing between versions. Even if the Delphi stack does not generate everything automatically, maintaining a specification as a central artifact is worthwhile.
Pragmatic test coverage that reduces operating costs
A sensible test structure for REST services usually consists of three levels:
- Unit tests for domain logic (without HTTP, without database)
- Integration tests for data access and transaction behaviour (with a test database and reproducible seed data)
- API/contract tests against a running service (status codes, auth, error formats, versioning)
For administrators and operations teams the crucial point is: tests must be reproducible and must not depend on developer environments. The closer the test environment resembles the eventual deployment, the lower the risk of surprises after updates.
Deployment and operations: Windows service, Linux service, containers
An REST server is only considered “complete” in practice when it can be operated stably: start/stop behaviour, log rotation, updates, permissions, port openings, certificates, monitoring and clear rollback options.
Windows and Linux services: proven operating models
Under Windows running as a Windows service is often natural because mechanisms for start type, recovery, permissions and monitoring are available. Under Linux a systemd service is frequently used (systemd is the standard service manager) and controls restart policies, logging integration and start ordering. For both worlds a reverse proxy in front simplifies TLS, header policies, rate limits and routing.
Containers: reproducible, but only with clean state separation
Containers can unify deployments and accelerate rollouts. The prerequisite is clear separation of state: database external, files in volumes, secrets via a secret management system. Without this discipline unmanageable mixed states arise that surface in incidents or restore scenarios.
Configuration: auditable, environment-separated, no secrets in the repo
A consistent configuration model helps: separate settings for Dev/Test/Prod, central definition of log levels, DB connection data, timeouts, allowed origins and token keys. Sensitive information should not be in the source repository. For audits and operations it is important that configuration changes are auditable and can be rolled out in a controlled manner.
Observability: logs, metrics and tracing as operational prerequisites
When integrations stall, operations need answers: which endpoints are affected, since when, at what error rate, and which dependency is slow? Without observability every incident becomes manual detective work.
Structured logging and correlation IDs
Structured logging (key/value or JSON) enables analysis by tools and simplifies filtering by endpoint, tenant, error code or correlation ID. Every request should receive a correlation ID that is also returned in the response header. Sensitive data such as passwords, tokens or personal content should not be logged; masking, hashing or targeted debug logs in isolated environments help here.
Metrics for capacity and stability
Practically proven metrics include request rate, latencies (e.g. p95/p99), error rates per endpoint, DB times, number of active workers/threads, connection utilisation and queue lengths. These values form the basis for capacity planning and help detect creeping problems (missing indexes, new dependencies, suboptimal query paths).
Modernization path: REST as a stable boundary for grown Delphi systems
In many Delphi landscapes the REST API is not the final state but a stability and modernization building block. A proven, low-risk approach is incremental:
- Prioritize use-cases: which functions must be externally available (master data, status changes, document access, approvals)?
- Define API standards: auth, error format, versioning, logging, timeouts, rate limits, OpenAPI.
- Extract the domain: structure business logic so it is not bound to the UI or individual endpoints.
- Consolidate data access: FireDAC rules, transaction concept, performance baselines, query policies.
- Gradually migrate consumers: desktop, portals and other services use the API; direct DB access is reduced.
The result is a system that can be evolved in stages: modules can be renewed without uncontrolled changes propagating to all clients.
Typical pitfalls in B2B REST projects
Some failure patterns recur and are avoidable with clear rules:
- Inconsistent error formats: support and integration become unnecessarily difficult. Solution: standardized error object with stable error codes.
- Security as an afterthought: roles, multi-tenancy and audit are added “later”. Solution: plan them as a foundational structure, not improvise per endpoint.
- No limits: missing body limits, timeouts and parallelism limits lead to outages under load. Solution: reverse proxy plus server-side backpressure.
- Database too tightly coupled to the API: every schema change breaks consumers. Solution: DTOs and clearly defined use-cases.
- Insufficient observability: problems are not measurable. Solution: correlation IDs, structured logs, core metrics.
Conclusion: REST with Delphi means responsibility for interface and operation
Developing a REST server with Delphi is sustainably successful in enterprise environments when architecture and operations are planned together from the start. Framework choice (WebBroker, Horse, RAD Server or a migration path from DataSnap) is relevant but not the biggest lever. What makes the difference are clear standards for API design, authentication, error handling, versioning, FireDAC data access, timeouts as well as observability and deployment as a Windows- or Windows- und Linux-Services. That turns an interface into a stable integration building block that enables modernization instead of blocking it.
In the technical context Delphi REST-API and Delphi REST-API and REST-server also play an important role when integrations, data flows and further development must work together cleanly.
Discuss a project or modernization initiative with Net-Base.
Next step
When the topic becomes a real project, architecture, the existing system landscape and operations should be considered together early on.
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 as afterthoughts.
- You can determine early which path is economically and operationally viable.