Du thème du magazine à la pratique des projets
Pages de services et techniques pertinentes pour l'article
Dans de nombreux services informatiques, la situation de départ est similaire : une application de bureau Delphi stable et proche des processus porte des opérations critiques, tandis que de nouvelles exigences poussent vers le web, les portails, l’utilisation mobile et l’intégration avec des services cloud. Parallèlement, C# s’est imposé dans de nombreuses entreprises pour les services, les Web-APIs et l’intégration d’identité. La question centrale n’est donc plus « Delphi ou C# ? », mais : combiner C# et Delphi dans une architecture commune de façon à maintenir la maîtrise de l’exploitation, de la maintenance, du stockage des données et de la sécurité.
Cet article décrit des principes d’architecture pragmatiques, éprouvés dans des environnements d’entreprise où il n’est ni possible ni souhaitable de tout reconstruire. L’accent est mis sur des responsabilités claires entre le client de bureau, les services, les données et les interfaces — et sur la manière de planifier des étapes de modernisation à risque maîtrisé, sans compromettre les processus en cours.
Pourquoi les piles technologiques mixtes sont la norme dans les entreprises
Les solutions numériques d’entreprise issues d’une évolution organique naissent rarement sur une page blanche. Les applications Delphi ont souvent été étendues pendant de nombreuses années, proches des processus métier, avec une logique de données conséquente et un savoir-faire approfondi sur les cas particuliers. Parallèlement, de nouvelles exigences sont apparues : portails en self-service, échanges de données automatisés, connexion à DMS/CRM/ERP, prise en charge du multi‑tenancy, renforcement de l’auditabilité ou authentification unique (Single Sign-on).
C# offre dans ce contexte souvent des avantages pour les écosystèmes web et services : large spectre d’hébergement, middleware standardisée, bonne intégration aux Identity Provider et patterns établis pour les Web-APIs. Delphi reste en revanche robuste lorsqu’il s’agit de clients desktop Windows performants, d’applications VCL entretenues à long terme ou de clients multiplateformes spécifiques (p. ex. via FMX).
Le mélange n’est donc pas un « cas particulier », mais une réponse réaliste à la protection des investissements et à la pression de modernisation. L’essentiel est que l’exploitation conjointe ne se transforme pas en chantier permanent.
Principe d’architecture : couches claires plutôt que frontières linguistiques
Lorsque deux langages coexistent, la tentation est grande d’organiser la séparation selon la technologie (« Tout ce qui est Delphi est Legacy, tout ce qui est C# est neuf »). Techniquement, cela peut fonctionner à court terme, mais à long terme cela engendre des frictions : règles métier dupliquées, responsabilités floues et erreurs difficiles à reproduire.
En pratique, une stratification fonctionnelle a fait ses preuves, souvent mise en œuvre comme une Layer-3 Architektur : présentation (UI), domaine (logique métier) et infrastructure (accès aux données, systèmes externes). L’important n’est pas le modèle théorique, mais l’effet concret au quotidien : décisions sur les données, validations et workflows sont prises en un seul endroit et exposées via des interfaces stables.
Dans une architecture mixte, cela signifie concrètement : Delphi peut continuer à fournir une partie UI (ou certains workflows), tandis que C# Services encapsulent une couche de domaine métier — ou inversement. Il est essentiel que la frontière entre les couches soit techniquement propre et testable.
C# et Delphi dans une architecture commune : trois modèles d’intégration éprouvés
Il n’existe pas « une » unique bonne façon de coupler Delphi et C#. De bonnes décisions se fondent sur l’exploitation, les exigences de sécurité, la latence, le volume de données et les cycles de publication. Dans la pratique, trois modèles se sont imposés.
1) Orientation service via HTTP/REST comme couplage standard
Le couplage via des API REST (interfaces basées sur HTTP) est souvent le plus robuste pour l’exploitation et l’évolution. Les clients Delphi appellent des services C# ou Delphi ; les portails C# utilisent les mêmes endpoints. Ce découplage rend les releases plus prévisibles : une mise à jour du client n’est pas nécessaire si l’API reste rétrocompatible.
Il est essentiel d’appliquer une conception professionnelle : timeouts, retries, idempotence (requêtes répétables sans effets secondaires), codes d’erreur clairs et une stratégie de gestion des versions. Pour l’administration et l’exploitation, il faut en outre : des logs uniformes, des Request-IDs traçables et des temps de réponse facilement mesurables.
2) Base de données commune : uniquement avec des règles claires
Un accès partagé à la base de données par Delphi et C# est tentant car il est rapide au départ. À long terme, il devient risqué si les deux mondes écrivent directement dans les mêmes tables. En effet, les règles métier migrent vers des triggers, des stored procedures ou « quelque part dans le client ». Cela complique l’analyse des erreurs et les audits.
Si une base de données commune est inévitable (p. ex. en phases de transition), des règles claires aident :
- Centraliser les écritures : un système est « System of Record » pour certaines entités.
- Définir des contrats : des vues ou des API comme couche de lecture stable plutôt que des accès directs aux tables.
- Planifier des fenêtres de migration : déployer les changements de base de données de manière rétrocompatible (p. ex. rendre les nouvelles colonnes optionnelles en premier).
D’un point de vue technique, la base de données devient alors un composant d’infrastructure, pas un bus d’intégration.
3) Messaging/Events pour les processus asynchrones
Pour les flux découplés (p. ex. importations, notifications, post-traitement, jobs d’interface), un modèle asynchrone est pertinent : un système publie des événements, un autre les consomme. Cela réduit les dépendances directes et stabilise les pics de charge.
Pour les responsables IT et les administrateurs, les points importants sont : le monitoring (longueurs des files d’attente), les mécanismes de Dead-Letter (messages échoués), le comportement de reprise et une idempotence métier clairement définie. Les événements ne remplacent pas une gestion rigoureuse des données de référence, mais constituent un outil efficace pour des chaînes de processus robustes.
Contrats de données et compatibilité : le noyau sous-estimé
Indépendamment du modèle d’intégration, la qualité des contrats de données conditionne la stabilité. Un contrat de données est la description contraignante des champs, des types, des obligations/optionnalités et de la sémantique. Dans les API REST, il s’agit typiquement de JSON ; l’important n’est pas « JSON en soi », mais la discipline dans la gestion des changements.
Règles éprouvées qui simplifient sensiblement l’exploitation :
- Étendre plutôt que casser : ajouter des champs, continuer à fournir les anciens champs dans un premier temps.
- Documenter la sémantique des champs : pas seulement « string », mais par exemple date ISO, fuseau horaire, états autorisés.
- Traiter les valeurs d’énumération de façon tolérante : les clients doivent tolérer des valeurs inconnues (compatibilité vers l’avant).
- Utiliser la gestion des versions d’API de manière raisonnée : chaque release n’exige pas une nouvelle version ; mais les breaking changes doivent être clairement encapsulés.
Ces points sont particulièrement importants lorsque les clients desktop Delphi ne peuvent pas être mis à jour aussi fréquemment que les services web.
Authentification et autorisation : un modèle de sécurité commun
Les architectures mixtes échouent rarement à cause de la « technique », plus souvent à cause d’une sécurité incohérente. Pour l’entreprise, l’essentiel est : qui peut faire quoi ? Comment est-ce vérifié ? Comment est-ce audité ? Un modèle commun évite les doubles gestions d’utilisateurs et les rôles contradictoires.
En pratique, cela conduit à une couche d’identité centralisée : par exemple via SAML 2.0 (authentification unique fédérée, fréquente en environnement entreprise) ou OpenID Connect (basé sur OAuth2, souvent utilisé pour des API Web modernes). C#-Services peuvent généralement être connectés directement à un fournisseur d’identité ; Delphi-Clients peuvent obtenir des jetons et les joindre aux appels d’API. Il est important que les applications de bureau n’obtiennent pas non plus de « droits spéciaux » via un accès direct à la base de données.
Points centraux pour les administrateurs :
- Durées de vie des jetons et stratégie de rafraîchissement (pour garantir la stabilité des clients tout en maintenant la sécurité)
- Authentification service-à-service pour la communication interne (p. ex. mTLS ou jetons signés)
- Principe du moindre privilège : ne pas définir les rôles et les permissions trop grossièrement
- Journaux d’audit : consigner de manière traçable les actions relevant de la sécurité
Concepts d’exploitation : Windows- et Linux-Services, IIS et processus au quotidien
Une architecture n’est « bonne » pour une entreprise que si elle est opérable : mises à jour planifiables, localisation des erreurs, maîtrise de la charge. Dans des environnements mixtes, les variantes d’exploitation les plus fréquentes sont :
- Windows- und Linux-Services : adaptés aux tâches en arrière-plan, aux traitements d’interface et aux workers ; bien intégrables dans des modèles d’exploitation serveur Windows classiques.
- Windows- und Linux-Services/Daemon : pertinent pour des modèles d’exploitation containerisés ou basés sur des VM ; souvent stable en fonctionnement continu, bonne automatisation via systemd.
- Microsoft IIS : hébergement établi pour les applications Web et les scénarios de reverse-proxy dans des environnements centrés sur Windows.
Il est important que les composants Delphi et C# respectent des standards d’exploitation similaires : endpoints de santé cohérents (indicateurs de vie), timeouts définis, consommation de ressources limitée, ainsi qu’une procédure claire de déploiement et de rollback. Cela réduit les traitements exceptionnels « spécifiques à une technologie ».
Journalisation, traçage et métriques : un niveau d’observabilité commun
Surtout avec deux stacks technologiques, des chaînes de diagnostic continues sont essentielles. Un problème typique : le client Delphi signale « erreur lors de l’enregistrement », le service C# subit un timeout, la base de données signale des verrous — sans lien commun.
Les pratiques éprouvées en production sont :
- IDs de corrélation par requête (Client → API → DB) afin de pouvoir regrouper les logs.
- Journalisation structurée (clé/valeur plutôt que lignes de texte brutes) pour permettre le filtrage ultérieur.
- Métriques pour la latence, les taux d’erreur, les longueurs de file d’attente et l’utilisation des ressources.
- Classification des erreurs : erreurs métier (validation) séparées des erreurs techniques (timeout, réseau).
Ces fondamentaux font gagner en pratique plus de temps que n’importe quelle discussion sur « la bonne langue ».
Accès aux données et migration : BDE-remplacement, FireDAC et bases de données modernes
Dans les installations Delphi, l’accès aux données a historiquement une grande importance. Lorsque des voies d’accès anciennes comme la Borland Database Engine (BDE) sont encore utilisées, cela crée une pression supplémentaire : mises à jour du système d’exploitation, migrations vers le 64 bits, disponibilité des pilotes, exigences de sécurité. Un BDE-remplacement n’est alors pas seulement une modernisation, mais une réduction du risque.
Il est courant de migrer vers un BDE-remplacement avec connexion native (couche d’accès aux données moderne dans Delphi), combiné avec une base de données facile à administrer (p. ex. PostgreSQL, SQL Server, MariaDB). Pour une architecture commune Delphi/C#, deux aspects sont importants :
- Limites de transaction : qui initialise/valide (commit) les transactions, et comment les écritures parallèles sont-elles régulées ?
- Stratégie de verrouillage et d’isolation : afin que les workflows côté poste de travail et les services ne se bloquent pas mutuellement.
Pour les migrations, une planification par étapes s’avère efficace : moderniser d’abord le pilote et la couche d’accès, puis consolider le modèle de données, ensuite stabiliser les interfaces d’intégration. Ainsi, les sources d’erreur deviennent isolables et les rollbacks réalistes.
Release-Management : concilier des cycles de mise à jour différents
Un point de tension récurrent est la fréquence des mises à jour : les web services peuvent être déployés plus fréquemment, les clients desktop souvent moins (fenêtres de déploiement, communication utilisateur, empaquetage). Une architecture commune doit tenir compte de cette asymétrie.
Conséquences pratiques :
- Compatibilité descendante de l’API est une obligation, pas une option.
- Feature Flags (commutateurs fonctionnels) permettent d’activer de nouvelles fonctionnalités de manière contrôlée côté serveur.
- Migrations de schéma doivent se dérouler par phases : étendre d’abord la base de données, puis utiliser le service, puis mettre à jour le client.
- Dépréciation claire : retirer les anciens endpoints ou champs uniquement après une période définie.
Particulièrement dans des environnements régulés, il est important de fixer ces règles par écrit comme lignes directrices d’architecture, afin que les décisions ne soient pas réinventées au cas par cas.
Pièges typiques et comment les éviter systématiquement
Du point de vue de l’exploitation, les problèmes les plus fréquents dans des environnements mixtes Delphi/C# sont bien prévisibles. En les traitant tôt, les coûts à long terme diminuent sensiblement.
Piège 1 : logique métier dupliquée
Lorsque le client Delphi et le service C# implémentent différemment les mêmes règles, des « erreurs fantômes » apparaissent : un processus fonctionne dans l’UI mais échoue lors de l’import via l’API. Contre‑mesures : centraliser les règles dans la couche domaine (service) ou les attribuer clairement sur le plan métier, y compris des réponses de validation explicites.
Piège 2 : contournements UI au lieu d’interfaces propres
« Écrire rapidement un champ de base de données » peut sembler inoffensif isolément, mais crée des interfaces fantômes sans journalisation, authentification ni versioning. Mieux : passer systématiquement par des endpoints définis, même si cela exige davantage de discipline au départ.
Piège 3 : responsabilités d’exploitation floues
Si on ne sait pas quelle équipe est responsable de quel service, quel journal et quels paramètres d’exploitation, la recherche d’erreur se transforme en ping-pong. Pratique : une cartographie des services (quel service, quelles dépendances, quels ports, quels SLA internes) et des Runbooks uniformes pour les incidents fréquents.
Piège 4 : manque de cohérence en matière de sécurité
Un portail avec SSO, mais un client desktop avec des comptes administrateur locaux pose souvent problème lors des audits. Un modèle d’identité et de rôles commun réduit le risque et la charge de support.
Aide à la décision : ce qui reste dans Delphi, ce qui va dans C# ?
La répartition appropriée dépend moins de l’idéologie que de la proximité des processus et des exigences d’exploitation. À titre d’orientation, du point de vue de l’architecture et de l’exploitation :
- Delphi convient souvent pour : clients desktop Windows existants (VCL), workflows UI très réactifs, scénarios proches de l’offline, maintenance à long terme d’interfaces historiques.
- C# convient souvent pour : APIs centrales REST, services d’intégration vers ERP/DMS/CRM, composants proches de l’identité, portails et processus backend avec une forte fréquence de changements.
- Décision consciente : la logique métier et la validation ne devraient pas être implémentées « dans le client » lorsque plusieurs frontends existent (desktop, portail, jobs d’import).
Important : l’objectif n’est pas « tout vers C# », mais une architecture globale robuste dans laquelle les étapes de modernisation sont planifiables et les processus métiers restent stables.
Parcours de modernisation : progressivement de l’application au système
Dans la pratique, une architecture commune est souvent une transition, mais une longue. Un parcours de modernisation réaliste évite les grands projets à haut risque et mise sur des objectifs intermédiaires mesurables :
- Stabiliser les interfaces : introduire l’API REST comme frontière fonctionnelle, même si tout n’est pas encore « propre » en interne.
- Moderniser l’accès aux données : BDE-remplacement, pilotes, compatibilité 64 bits, transactions claires.
- Centraliser l’identité : SSO et modèle de rôles pour tous les modes d’accès.
- Uniformiser l’exploitation : logging/monitoring/health, déploiements clairs, environnements reproductibles.
- Découpler les modules fonctionnels : déplacer les parties à forte fréquence de changements vers des services, alléger progressivement l’UI.
Cet ordre n’est pas dogmatique, mais il minimise typiquement les dépendances : sans interfaces stables et concept d’exploitation, toute modification ultérieure coûte davantage.
Conclusion : l’intégration est une tâche d’architecture, pas une question de langage
Une combinaison viable de Delphi et C# ne naît pas de « bibliothèques passerelles », mais de frontières fonctionnelles claires, de contrats de données propres et d’un concept d’exploitation qui prend au sérieux le monitoring, la sécurité et la gestion des releases. Lorsque C# et Delphi dans une architecture commune interagissent consciemment selon les responsabilités, les entreprises gagnent avant tout une chose : la modernisation sans rupture des processus. Delphi peut continuer à supporter fiablement des workflows desktop stables, tandis que les services C# fournissent l’intégration, les Web-APIs et les portails comme fonctions centrales de plateforme.
Si vous souhaitez moderniser progressivement un parc Delphi existant ou connecter proprement des services C#, une revue d’architecture portant sur les interfaces, les données, l’exploitation et la sécurité est la voie la plus rapide vers des décisions solides. Plus d’informations lors d’un échange direct :
Dans le contexte métier, la Delphi modernisation et la REST-API jouent également un rôle important pour les logiciels existants, lorsque les intégrations, les flux de données et l’évolution doivent s’articuler proprement.
Étape suivante
Lorsque ce sujet devient un projet concret, l'architecture, l'existant et l'exploitation doivent être examinés ensemble dès le départ.
Nous n'intervenons pas seulement sur des questions ponctuelles, mais aussi lorsque des fragments de code source, des problématiques liées aux systèmes legacy ou des concepts de portail doivent se transformer en un projet d'entreprise robuste.
- L'état des lieux, l'état cible et les risques techniques sont évalués conjointement.
- REST, l'accès aux données, les portails et le déploiement ne sont pas repoussés en tant que conséquences ultérieures.
- Vous identifiez tôt quelle voie est viable sur le plan économique et opérationnel.