Intégrations internes et externes
Les intĂ©grations connectent lâapplication gĂ©nĂ©rĂ©e par Lino Ă dâautres modules, services internes et systĂšmes tiers. Le choix entre appel synchrone, intĂ©gration in-process, HTTP et Ă©vĂ©nements doit tenir compte du couplage, de la latence, de la fiabilitĂ© et de la propriĂ©tĂ© des donnĂ©es.
Lâobjectif nâest pas seulement dâappeler un autre systĂšme. Il sâagit de dĂ©clarer une frontiĂšre : qui fournit la donnĂ©e, qui la consomme, quel contrat est public, ce qui se passe en cas dâĂ©chec et si lâopĂ©ration doit ĂȘtre immĂ©diate ou peut ĂȘtre traitĂ©e plus tard.
Créer des intégrations
Les intĂ©grations reprĂ©sentent une communication explicite avec un autre contexte, un service interne ou un systĂšme externe. Elles doivent avoir un nom, un contrat, une authentification, un timeout, une stratĂ©gie dâerreur et une responsabilitĂ© claire.
lino integration new --name <ServiceName> lino integration list
Utilisez integration list pour vĂ©rifier les intĂ©grations existantes avant dâen crĂ©er une autre. Ăvitez les intĂ©grations gĂ©nĂ©riques, comme CommonIntegration, car elles tendent Ă accumuler des responsabilitĂ©s sans limite claire.
Avant de crĂ©er une intĂ©gration, dĂ©finissez le problĂšme quâelle rĂ©sout : consulter un registre externe, envoyer une facturation, valider un abonnement, synchroniser un utilisateur, consommer un module interne ou publier des donnĂ©es vers un autre systĂšme. Si lâintĂ©gration nâa pas dâintention spĂ©cifique, elle nâest probablement pas encore prĂȘte Ă devenir un contrat gĂ©nĂ©rĂ©.
- Nommez par le contexte intégré : préférez
Billing,Identity,CatalogouShippingaux noms gĂ©nĂ©riques. - SĂ©parez contrat et implĂ©mentation : le domaine et lâapplication ne doivent pas dĂ©pendre directement des dĂ©tails de transport.
- Supposez les défaillances externes : toute intégration distante peut devenir lente, indisponible, retourner une erreur partielle ou changer son contrat.
Resources dâintĂ©gration
Les resources représentent des objets exposés ou consommés par une intégration, comme customers, invoices, tenants, subscriptions, users ou documents.
lino integration resource new --service <ServiceName> --module <ModuleName> --entity <EntityName> lino integration resource list --service <ServiceName> --module <ModuleName> --entity <EntityName>
Un resource dâintĂ©gration nâa pas besoin dâĂȘtre identique Ă lâentitĂ© de domaine. Il sâagit souvent dâun contrat dâĂ©change de donnĂ©es, dâune vue externe ou dâune reprĂ©sentation minimale nĂ©cessaire Ă la communication entre contextes. Copier toute lâentitĂ© dans le contrat externe expose souvent des dĂ©tails internes et augmente le coĂ»t dâĂ©volution.
- Modélisez le resource avec le vocabulaire du systÚme intégré.
- Nâexposez pas les entitĂ©s internes comme contrat externe.
- Définissez quels champs sont des identifiants, des filtres et des données retournées.
- Documentez la pagination, lâauthentification et les limites dâappel lorsquâelles existent.
Lorsque le resource reprĂ©sente des donnĂ©es dâun autre module, incluez seulement ce qui est nĂ©cessaire au consommateur. Le mĂȘme principe apparaĂźt dans les shadow entities : le module consommateur conserve une petite copie locale, alignĂ©e sur son propre cas dâutilisation, au lieu de dĂ©pendre du modĂšle complet du module producteur.
OpĂ©rations dâintĂ©gration
Les opĂ©rations dĂ©crivent les actions disponibles sur un resource dâintĂ©gration : crĂ©er, consulter, mettre Ă jour, annuler, envoyer, synchroniser ou valider.
lino integration operation new --service <ServiceName> --module <ModuleName> --entity <EntityName> lino integration operation list --service <ServiceName> --module <ModuleName> --entity <EntityName>
Chaque opĂ©ration doit dĂ©finir son intention, son entrĂ©e, sa sortie, sa mĂ©thode dâappel, son comportement dâerreur et si elle peut ĂȘtre rĂ©exĂ©cutĂ©e en sĂ©curitĂ©.
- Les requĂȘtes doivent avoir un timeout et une gestion de lâindisponibilitĂ©.
- Les commandes distantes doivent ĂȘtre idempotentes lorsque câest possible.
- Les défaillances externes ne doivent pas casser la transaction principale si le métier accepte un traitement asynchrone.
- Utilisez des logs et un correlation id pour tracer les appels entre systĂšmes.
Lâidempotence est particuliĂšrement importante dans les opĂ©rations dâĂ©criture. Si une tentative Ă©choue aprĂšs que le systĂšme externe a exĂ©cutĂ© lâaction, une nouvelle tentative peut dupliquer une facturation, crĂ©er un enregistrement rĂ©pĂ©tĂ© ou envoyer un message deux fois. Lorsque câest possible, utilisez des clĂ©s dâidempotence, des identifiants externes ou des rĂšgles de rĂ©exĂ©cution documentĂ©es.
Consommer des intégrations
AprĂšs avoir modĂ©lisĂ© une intĂ©gration, un resource et une opĂ©ration, utilisez la consommation pour connecter lâapplication au contrat gĂ©nĂ©rĂ©. Lâobjectif est de faire dĂ©pendre le cas dâutilisation dâune abstraction nommĂ©e, avec une entrĂ©e et une sortie prĂ©visibles, au lieu de disperser les appels HTTP, lâassemblage dâURL, les headers, le parsing de rĂ©ponse et la gestion dâerreur dans plusieurs handlers.
lino integration consume
Les Use Cases doivent dĂ©pendre dâabstractions, pas de dĂ©tails HTTP dispersĂ©s dans le code. Cela facilite les tests, le remplacement dâimplĂ©mentation et la gestion uniforme des dĂ©faillances. Cela Ă©vite aussi que chaque endpoint de lâapplication rĂ©invente diffĂ©remment timeout, authentification, correlation id, sĂ©rialisation et mapping dâerreur.
- Validez les donnĂ©es avant dâappeler un service externe.
- Utilisez cancellation token et timeout.
- Mappez les réponses externes vers des erreurs internes prévisibles.
- Nâenregistrez pas un payload externe brut comme rĂšgle de domaine sans transformation.
HTTP vs. in-process
LâintĂ©gration in-process est simple et rapide lorsque les modules sâexĂ©cutent ensemble. HTTP crĂ©e un contrat plus explicite entre processus, mais ajoute de la latence, des dĂ©faillances rĂ©seau et un besoin de rĂ©silience.
LâintĂ©gration in-process ne doit pas signifier un accĂšs libre Ă tout. MĂȘme dans le mĂȘme runtime, le consommateur doit communiquer par contrat, et non par entitĂ© interne, DbContext ou repository dâun autre module. Le coĂ»t rĂ©seau est plus faible, mais le risque de couplage existe toujours.
| Scénario | Choix courant | Observation |
|---|---|---|
| Modules dans le mĂȘme monolithe modulaire | In-process ou contrat interne | PrĂ©servez la frontiĂšre ; Ă©vitez de partager entitĂ© et persistance. |
| Service séparé avec son propre déploiement | HTTP ou messagerie | Traitez réseau, authentification, versionnement et indisponibilité. |
| Processus asynchrone et tolĂ©rant au dĂ©lai | ĂvĂ©nement dâintĂ©gration | Concevez des consommateurs idempotents et traçables. |
HTTP est plus adaptĂ© lorsque le producteur et le consommateur ont des runtimes sĂ©parĂ©s ou lorsque vous voulez rendre la frontiĂšre opĂ©rationnellement explicite. In-process est adaptĂ© lorsque la mĂȘme application hĂ©berge les contextes et que la rĂ©ponse doit ĂȘtre immĂ©diate, Ă condition que la dĂ©pendance reste dĂ©clarĂ©e par contrat.
ĂvĂ©nements vs. intĂ©grations synchrones
Utilisez une intĂ©gration synchrone lorsque la rĂ©ponse est nĂ©cessaire pour terminer lâopĂ©ration en cours. Utilisez un Ă©vĂ©nement lorsque le consommateur peut rĂ©agir plus tard et que la consistance Ă©ventuelle est acceptable.
Ce choix est une dĂ©cision mĂ©tier avant dâĂȘtre une dĂ©cision technique. Si une commande ne peut ĂȘtre créée quâaprĂšs confirmation dâautorisation par le service de paiement, lâappel synchrone peut ĂȘtre une partie essentielle du cas dâutilisation. Si la crĂ©ation de la commande doit seulement dĂ©clencher une notification, une mise Ă jour de projection ou une synchronisation vers un autre module, un Ă©vĂ©nement tend Ă ĂȘtre plus appropriĂ©.
| Besoin | Approche | Attention technique |
|---|---|---|
| Réponse immédiate obligatoire | Intégration synchrone | Timeout, fallback, erreur prévisible et contrat stable. |
| Effet ultĂ©rieur tolĂ©rant au dĂ©lai | ĂvĂ©nement dâintĂ©gration | Outbox, idempotence, retries et logs de corrĂ©lation. |
| Lecture fréquente de peu de données externes | Shadow Entity ou projection locale | Synchronisation, mise à jour éventuelle et modÚle minimal. |
