Qu'est-ce que MIC ?¶
MIC signifie Model / Interface / Controller. C'est une structure pour des services de production en Python ou en Node.js / TypeScript :
- Model : représentations stables de la donnée, contrats et règles métier ;
- Interface : contrats entrants et sortants, exprimés indépendamment du framework qui les transporte ;
- Controller : orchestration fine qui relie Model et Interface pour exécuter un cas d'usage.
C'est MVC retourné : le framework HTTP n'est pas au centre. Le métier reste au centre, tandis que FastAPI, Litestar, Express, Fastify, Hono, NestJS ou Node HTTP deviennent des adaptateurs remplaçables.
Le contrat MIC en une image¶
graph TB
A[Client HTTP] -->|requête| B[Adaptateur Python<br/>FastAPI / Litestar]
A -->|requête| C[Adaptateur Node.js<br/>Node HTTP / Express / Fastify / Hono / NestJS]
B --> D[Contrat de route<br/>HttpRouteSpec / route]
C --> D
D --> E[Controller<br/>handler]
E --> F[Model<br/>service métier]
F --> G[(Persistance<br/>propre au service)]
F --> H[Service externe<br/>client signé]
E --> I[Résultat HTTP<br/>canonique]
I --> B
I --> C
B -->|réponse| A
C -->|réponse| A
Le nom des primitives suit l'idiome du langage, mais la frontière reste la même : un contrat de route décrit l'entrée, la sortie et les erreurs ; le gestionnaire exécute le métier ; l'adaptateur traduit le résultat vers le framework choisi.
Un contrat, deux idiomes¶
| Besoin | Python | Node.js / TypeScript |
|---|---|---|
| Contrat statique ou gouverné | StrictSchema, SchemaRegistry |
schema, GovernedSchemaRegistry |
| Erreur définitive ou transitoire | DomainError, TransientError |
DomainError, TransientError |
| Route indépendante du framework | HttpRouteSpec |
route() |
| Client inter-service signé | ServiceHttpClient |
ServiceHttpClient |
| Persistance à portée d'organisation | TenantScopedRelationalStore |
TenantScopedRelationalStore |
| Adaptateurs HTTP | FastAPI, Litestar | Node HTTP, Express, Fastify, Hono, NestJS |
| Générateur | cookiecutter mic-python |
@mic-struct/create-mic-service |
Cette correspondance est une doctrine partagée, pas une couche de compatibilité cachée. Chaque implémentation reste idiomatique dans son langage. Les services communiquent par des contrats explicites, par exemple OpenAPI, des événements versionnés ou des messages strictement validés.
Trois couches, trois responsabilités¶
Model¶
Tout ce qui décrit quoi : schémas statiques ou gouvernés, entités, erreurs de domaine, invariants et services métier. Cette couche ne connaît ni objet de requête HTTP, ni décorateur de framework, ni connexion globale.
Les contrats rejettent les champs inconnus. Les erreurs possèdent un code stable et déclarent si une reprise est possible. Les dépendances sont reçues explicitement.
Interface¶
Tout ce qui décrit comment le service parle aux mondes extérieurs : routes HTTP, authentification, clients inter-services, événements, files de messages et commandes opérateur.
Une interface MIC publie suffisamment de métadonnées pour être vérifiée et documentée. En HTTP, le même contrat alimente l'adaptateur d'exécution et le document OpenAPI.
Controller¶
Tout ce qui décrit quand : gestionnaires HTTP, consommateurs, workers et tâches périodiques. Un contrôleur reçoit des données déjà validées, appelle le service métier puis retourne un résultat canonique. Il orchestre ; il ne porte pas les règles métier.
Ce que ce n'est pas¶
- Ce n'est pas un nouveau framework HTTP. Les frameworks restent en place ; MIC les utilise comme adaptateurs.
- Ce n'est pas Clean Architecture ou Hexagonal Architecture en costume. La frontière métier-infrastructure est commune, sans imposer une cérémonie de classes intermédiaires.
- Ce n'est pas un conteneur d'injection de dépendances. L'assemblage reste explicite, lisible et testable.
- Ce n'est pas un ORM. Le schéma de base, les migrations, les index et les requêtes propres au moteur restent la responsabilité du service.
- Ce n'est pas une abstraction qui gomme Python et TypeScript. MIC conserve leurs types, leurs outils et leurs conventions au lieu de fabriquer un plus petit dénominateur commun.
Pour qui ?¶
- Les équipes qui écrivent plusieurs services Python, TypeScript, ou les deux.
- Les équipes qui veulent les mêmes garanties minimales partout : contrats, erreurs, authentification, observabilité et tests.
- Les équipes qui veulent prouver la portabilité entre frameworks sans réécrire le métier.
Choisir une implémentation¶
- Quickstart Python — un endpoint en cinq minutes avec FastAPI ou Litestar.
- Quickstart Node.js / TypeScript — un service généré, vérifié et documenté par OpenAPI.
- Périmètre, maturité et sortie — ce que MIC prend en charge et ce qui reste au service.