Décisions architecturales avant de générer du code

Lino génÚre beaucoup de code rapidement, mais la qualité du résultat dépend des décisions prises avant la génération. Le choix des limites, du type de projet, de la stratégie de communication et du niveau acceptable de dette technique évite que la productivité initiale ne se transforme en retouche.

Utilisez cette page comme liste de contrÎle d'architecture pour aligner votre équipe, votre domaine et vos opérations avant de créer des services, modules et fonctionnalités avancés.

Type de projet

Avant de courir lino project new, dĂ©finir l’objectif du systĂšme. Un projet administratif interne, un SaaS multi-tenant, un API public et une plateforme distribuĂ©e ont des besoins diffĂ©rents.

  • Application simple : peu de contextes, dĂ©ploiement unique et faible besoin d’indĂ©pendance opĂ©rationnelle.
  • Monolithe modulaire : plusieurs modules dans le mĂȘme processus, avec des limites explicites et des coĂ»ts opĂ©rationnels infĂ©rieurs.
  • Microservices : services sĂ©parĂ©s, dĂ©ploiement indĂ©pendant, communication asynchrone et plus grande complexitĂ© opĂ©rationnelle.
  • SaaS : nĂ©cessite l'isolement des tenants, une sĂ©curitĂ© renforcĂ©e, des secrets, une limitation des tarifs, de l'observabilitĂ© et des dĂ©cisions claires en matiĂšre de facturation/d'exploitation.

Cette décision définit également quelles préoccupations devraient surgir dÚs le premier jour. Un SaaS ne peut pas traiter le tenant comme un détail tardif ; un API public ne peut pas naßtre sans limitation des tarifs et sans contrats clairs ; une solution avec des événements doit penser à Outbox, à l'idempotence et à l'observabilité ; une application avec plusieurs cultures doit éviter les chaßnes dispersées dÚs le début.

Lors de la création de la fondation, enregistrez les principaux choix : cultures prises en charge, cache distribué, communication asynchrone, analyseurs de code, type de base de données, présence de l'application Web, authentification, tenant et travailleur. Ces options affectent les packages, les templates, AppHost, les paramÚtres, les secrets, les projets générés et l'effort requis pour modifier l'architecture ultérieurement.

Microservices modulaires et modulaires monolithiques

Le monolithe modulaire vous permet d'organiser le domaine en modules avec des contrats internes clairs, ce qui simplifie la construction, le débogage et le déploiement. Les microservices ne sont payants que lorsqu'il existe de bonnes raisons: une échelle indépendante, des équipes distinctes, des frontiÚres commerciales stables ou des exigences opérationnelles différentes.

Commencer par un monolithe modulaire ne signifie pas ignorer l’architecture. Cela signifie prĂ©server un dĂ©ploiement simple pendant que le domaine est encore en cours de dĂ©couverte, mais crĂ©er des limites internes qui empĂȘchent que tout ne devienne une masse unique d'entitĂ©s, de services et de tables partagĂ©es. C’est la diffĂ©rence entre « dĂ©marrer simplement » et « dĂ©marrer sans structure ».

CritĂšreMonolithe modulaireMicroservices
DéployerLe plus simple, généralement uniqueIndépendant par service
CohérencePlus facile de maintenir des transactions localesNécessite des événements, Outbox et une cohérence éventuelle
OpĂ©rationCoĂ»t d’infrastructure rĂ©duitPlus d'observabilitĂ©, de files d'attente, de tentatives et d'automatisation
RefactorisationMoins cher au débutPlus difficile lorsque les contrats ont déjà été publiés

Lino prend en charge les deux chemins. La dĂ©cision doit suivre le domaine et la capacitĂ© opĂ©rationnelle de l'Ă©quipe, et pas seulement les prĂ©fĂ©rences techniques. Les microservices nĂ©cessitent l'automatisation du dĂ©ploiement, l'observabilitĂ© distribuĂ©e, la gestion des versions des contrats, la tolĂ©rance aux pannes du rĂ©seau, la messagerie, le retraitement et la gouvernance des donnĂ©es. Si l’équipe ne peut pas encore l’exploiter en toute sĂ©curitĂ©, une distribution trop prĂ©coce augmente souvent le risque.

Utilisez un monolithe modulaire lorsque la prioritĂ© est d'apprendre le domaine, de valider le produit et de garder l'opĂ©ration contrĂŽlable. Utilisez des microservices lorsque l’indĂ©pendance opĂ©rationnelle est dĂ©jĂ  un besoin concret: Ă©chelle distincte, Ă©quipes rĂ©ellement propriĂ©taires, cycle de publication indĂ©pendant ou exigences d’infrastructure incompatibles entre les parties du systĂšme.

Limites des services et des modules

Une bonne limite rĂ©duit le couplage et indique clairement Ă  qui appartient chaque rĂšgle. Évitez de crĂ©er des services par table ou par Ă©cran. Les services et modules doivent reprĂ©senter les capacitĂ©s mĂ©tier.

  • Catalogue: produits, catĂ©gories, informations commerciales et donnĂ©es consultĂ©es par les commerciaux.
  • Ventes: commandes, panier, prix appliquĂ©s, instantanĂ©s et flux commercial.
  • Action: disponibilitĂ©s, rĂ©servations et mouvements.
  • SĂ©curitĂ©: utilisateurs, rĂŽles, autorisations, authentification et jetons.

Une bonne limite a son propre langage, des rÚgles qui changent ensemble, des données clairement définies et des contrats explicites pour communiquer avec d'autres contextes. Une mauvaise limite apparaßt généralement comme un module « Commun », une entité partagée par plusieurs zones, un tableau consulté par tout le monde ou un service créé simplement parce qu'il y a eu un nouvel écran.

Lorsqu'un module a besoin des donnĂ©es d'un autre, choisissez entre API, un Ă©vĂ©nement d'intĂ©gration, une shadow entity ou un remodelage des limites. L'accĂšs direct Ă  la rive d'un autre module est le signe d'un couplage structurel. MĂȘme lorsque deux modules s'exĂ©cutent dans le mĂȘme processus et utilisent la mĂȘme base de donnĂ©es physique, le schĂ©ma, les projets de persistance et les contrats doivent protĂ©ger les limites mĂ©tier.

  • Signe de bonne limite : le module peut faire Ă©voluer ses entitĂ©s et ses migrations sans forcer un autre module Ă  se recompiler en raison de dĂ©tails internes.
  • Signal de seuil faible : une simple modification d'une entitĂ© nĂ©cessite de revoir les Ă©crans, les requĂȘtes et les gestionnaires de modules qui ne devraient pas connaĂźtre cette entitĂ©.
  • Signe de dĂ©pendance caché : le consommateur a besoin de « trop en savoir » sur les tableaux, les domaines techniques ou le rĂšglement intĂ©rieur du producteur.

Dette technique consciente

La dette technique n’est pas n’importe quelle imperfection. C'est une dĂ©cision de reporter la qualitĂ© en connaissant le coĂ»t futur. Le problĂšme est de crĂ©er une dette sans nom, sans propriĂ©taire et sans plan de paiement.

Dans un systÚme SaaS ou modulaire, la dette technique la plus dangereuse n'est pas seulement une longue méthode. C'est la dette qui limite l'évolution: modules qui ne peuvent pas changer séparément, données tenants sans isolation fiable, secrets au sein du référentiel, points de terminaison sensibles sans limites, événements sans retraitement ou intégrations sans contrat clair.

  • Documentez les raccourcis pris pendant la gĂ©nĂ©ration et la personnalisation.
  • ExĂ©cutez la compilation et les tests avant de passer Ă  l'Ă©tape de gĂ©nĂ©ration suivante.
  • Évitez de rĂ©soudre les problĂšmes gĂ©nĂ©rĂ©s par des hacks locaux rĂ©pĂ©tĂ©s ; ajustez le motif ou le modĂšle lorsque le motif est erronĂ©.

Traitez chaque décision architecturale comme vérifiable. Si vous choisissez de ne pas activer la messagerie, notez que les flux actuels ne reposent pas sur un traitement asynchrone. Si vous choisissez une colonne par tenant, assurez-vous des filtres et des tests. Si vous choisissez l'intégration synchrone, prenez en compte les délais d'attente, l'indisponibilité et les erreurs de contrat dans le cadre de la conception.

Stratégies de communication

Choisir la communication en fonction du besoin rĂ©el de cohĂ©rence, de latence, de traçabilitĂ© et de couplage. La question principale n’est pas « quelle technologie utiliser ? », mais « le producteur a besoin de la rĂ©ponse maintenant, si le consommateur n’annule pas l’opĂ©ration et Ă  qui appartiennent les donnĂ©es ? ».

Dans les systĂšmes modulaires, l'erreur la plus courante est de transformer la communication en dĂ©pendance cachĂ©e: un module interroge la table d'un autre, rĂ©utilise une entitĂ© interne, injecte un rĂ©fĂ©rentiel externe ou crĂ©e un appel synchrone sans gĂ©rer l'Ă©chec. Cela semble productif au dĂ©but, mais cela rend chaque changement ultĂ©rieur plus risquĂ© car la frontiĂšre n’est plus explicite.

  • Appel synchrone : bon pour consultation immĂ©diate et dĂ©pendance acceptable. A Ă©viter dans les longues cascades.
  • ÉvĂ©nement de domaine : rĂ©action interne dans la mĂȘme limite d'application.
  • ÉvĂ©nement d'intĂ©gration : communication entre modules, services ou systĂšmes, normalement avec Outbox.
  • EntitĂ©s fantĂŽmes : Copie locale minimum pour consultation et validation sans dĂ©pendre directement du producteur.
  • IntĂ©gration externe HTTP : adaptĂ© aux services tiers, avec dĂ©lai d'attente, nouvelle tentative, journaux et gestion des Ă©checs.

Si la rĂšgle nĂ©cessite une mise Ă  jour immĂ©diate, utilisez le flux synchrone ou revoyez la limite. Si vous acceptez une cohĂ©rence Ă©ventuelle, prĂ©fĂ©rez les Ă©vĂ©nements pour rĂ©duire le couplage. Lorsque le consommateur n’a besoin de lire qu’un petit sous-ensemble de donnĂ©es provenant d’un autre contexte, une shadow entity peut ĂȘtre plus sĂ»re que d’exposer l’intĂ©gralitĂ© de l’entitĂ© d’origine.

QuestionDirection recommandée
La rĂ©ponse est-elle requise pour terminer le cas d’utilisation ?IntĂ©gration synchrone explicite, avec dĂ©lai d'attente, erreur prĂ©visible et contrat clair.
Le producteur doit-il confirmer la transaction mĂȘme si le consommateur est absent ?ÉvĂ©nement d'intĂ©gration avec Outbox et traitement asynchrone.
Le consommateur n’a-t-il besoin que de valider ou de consulter un minimum de donnĂ©es ?EntitĂ© fantĂŽme alimentĂ©e par un Ă©vĂ©nement ou une intĂ©gration, avec propriĂ©tĂ© locale du modĂšle de lecture.
Le changement se produit-il dans le mĂȘme contexte global ou dĂ©limité ?ÉvĂ©nement de domaine ou logique locale de domaine, sans publier de contrat externe inutile.
Une erreur non gérée est survenue. Rafraîchir 🗙