Vue d'ensemble¶
Un service MIC place son noyau métier derrière des contrats exécutables et des dépendances explicites. Python et Node.js partagent cette architecture, mais conservent leurs paquets, leurs types et leurs conventions de composition.
MIC fournit la plomberie transversale. Le service reste propriétaire de son domaine, de ses données, de son déploiement et de ses objectifs de performance.
Schéma global¶
graph TB
C[Client HTTP] --> PA[Adaptateur Python]
C --> NA[Adaptateur Node.js]
PA --> R[Contrat de route]
NA --> R
R --> V[Auth et validation]
V --> CT[Controller / handler]
CT --> M[Model / métier]
M --> RP[Repository du service]
RP --> DS[(Stockage ou broker)]
M --> OC[Client signé / outbox]
M --> RS[Résultat canonique]
RS --> A[Adaptateur HTTP]
A --> HR[Réponse HTTP]
Le framework ne traverse pas la frontière du handler. Il traduit une requête native vers le contrat MIC, puis transforme le résultat canonique en réponse native. Le même handler peut donc être servi par un autre adaptateur sans réécrire le métier.
Trois propriétaires explicites¶
Le service possède¶
- les entités, invariants, cas d'usage et codes d'erreur métier ;
- les schémas de base de données, migrations, index et requêtes spécialisées ;
- les topics, payloads et politiques de version de ses événements ;
- la configuration, les secrets, le déploiement et la supervision des processus ;
- les objectifs de capacité, les tests de charge et l'acceptation en production.
MIC fournit¶
- des contrats statiques ou gouvernés, des enveloppes et des erreurs canoniques ;
- des routes indépendantes du framework et leurs adaptateurs HTTP ;
- l'authentification inter-service, le client signé et les contrôles de portée ;
- des ports et implémentations pour le stockage, l'outbox, les files, le cache, les verrous et les tâches périodiques ;
- des primitives de logs, métriques, tracing, santé, résilience et test.
L'infrastructure externe possède¶
- le cycle de vie du serveur HTTP et du processus ;
- les bases, brokers, caches, backends d'observabilité et fournisseurs d'identité ;
- l'ordonnancement, l'arrêt forcé, la rétention, les sauvegardes et la reprise.
Un adaptateur MIC relie ces systèmes au service. Il ne transfère pas leur exploitation ni leurs garanties à MIC.
Composition Python¶
L'implémentation Python est organisée autour de trois distributions PyPI qui
partagent l'espace de noms mic.* :
mic-corepour les contrats, routes, erreurs, auth, client et observabilité ;mic-datastorepour la persistance, l'outbox, les files, le cache, les verrous et la planification ;mic-platformpour les politiques d'autorisation, d'identité et de limitation de débit.
Un service structuré place généralement son code dans
app/modules/<domain>/, sépare model, controller et interface, puis
assemble les dépendances dans app/bootstrap/. Les routes
HttpRouteSpec restent indépendantes de FastAPI ou Litestar. Voir la
structure canonique Python et
l'organisation des paquets.
Composition Node.js¶
L'implémentation Node.js sépare les responsabilités en paquets npm :
@mic-struct/mic-corepour les schémas, routes, erreurs, auth et contrats OpenAPI ;@mic-struct/mic-clientet@mic-struct/mic-datastorepour les appels sortants et les primitives de données ;@mic-struct/mic-node-http,@mic-struct/mic-express,@mic-struct/mic-fastify,@mic-struct/mic-honoet@mic-struct/mic-nestpour les adaptateurs HTTP ;- les paquets Kafka, NATS, Redis, observabilité, résilience et plateforme pour les besoins optionnels.
@mic-struct/create-mic-service génère volontairement un point de départ compact
dans src/ avec routes, domaine d'exemple, serveur, OpenAPI et CLI opérateur.
Ces fichiers appartiennent ensuite à l'application : elle peut les répartir en
modules sans changer les contrats route() ni les handlers. Voir le
quickstart Node.js et le
dépôt mic-node.
Cycle d'une requête¶
- L'adaptateur du framework reçoit la requête HTTP native.
- La porte d'authentification vérifie le token, son audience, son émetteur et les portées requises.
- Le contrat de route valide les paramètres, les en-têtes et le corps.
- Le handler reçoit des données validées et des dépendances explicites.
- Le controller orchestre le cas d'usage ; le Model applique les invariants et appelle les repositories ou clients nécessaires.
- Une
DomainErrordécrit un échec permanent ; uneTransientErrorsignale qu'un nouvel essai peut réussir. - Le handler retourne un résultat canonique que l'adaptateur valide et sérialise.
- Les corrélations, traces et métriques couvrent la frontière sans entrer dans les règles métier.
Les noms précis suivent le langage, par exemple StrictSchema en Python et
schema.* en Node.js, mais l'ordre des responsabilités reste le même.
Ce que la portabilité garantit¶
La portabilité MIC signifie qu'un changement d'adaptateur ne modifie pas le comportement du handler, ses contrats ni ses tests métier. Elle ne signifie pas qu'un service Python et un service Node.js partagent le même code source ou le même modèle de données.
Pour évaluer cette frontière, testez séparément :
- le handler avec ses dépendances substituées ;
- le contrat public et ses erreurs ;
- chaque adaptateur utilisé par un test HTTP réel ;
- le document OpenAPI généré ;
- les stores et transports contre leurs moteurs réels avant la production.
Consultez aussi le périmètre et la stratégie de sortie pour distinguer les garanties du socle de celles qui restent propres au produit.