Modular Monolith is the new Microservices

Parler de monolithe modulaire en fin d'année 2025, c'est arriver un peu après la bataille. Nous avons tous souffert à essayer d'opérer 3 microservices sur Kubernetes managé et pleuré chaque mois en recevant la facture. Le principe du monolithe modulaire, plein d'un pragmatisme revigorant, a fait des émules. Cependant, son implémentation concrète mérite qu'on s'y attarde.
Des contextes déployés dans une même coquille
Rappelons pour commencer ce qu'est un monolithe modulaire :
- Le monolithe modulaire s'oppose au monolithe plat de spaghettis par sa structuration claire en bounded contexts . Cela signifie qu'une vraie démarche de DDD stratégique a été menée en amont. On sait où l'on met les pieds.
- Mais dans le même temps, le monolithe modulaire conserve la facilité de déploiement du monolithe, puisque les différents contextes sont déployés au sein d'une seule et même "coquille". Conséquence immédiate cependant : redéployer un contexte signifie redéployer tous les contextes (on ne peut pas avoir le beurre et l'argent du beurre).
La beauté du monolithe modulaire, c'est qu'il n'obère pas le futur : il sera toujours temps de passer en microservices si le besoin se fait sentir. Quand vous serez Google ou Netflix et que vous aurez des vrais problèmes de scalabilité 😉
Mise en œuvre : 4 principes essentiels
Cependant, une fois qu'on a dit ça, on n'a pas dit grand-chose. D'expérience, la mise en œuvre d'un monolithe modulaire soulève des questions. Voici 4 aspects qui me semblent particulièrement importants :
- Isoler le domaine à l'intérieur de chaque contexte, via une architecture hexagonale ou bien functional core / imperative shell. Ainsi, votre monolithe est une juxtaposition de jolis petits hexagones bien rangés les uns à côté des autres, même si l'API HTTP et l'infrastructure sont mutualisées.
- Si les différents contextes requièrent le même type de base de données (relationnel, document, graphe, clé-valeur etc.), cette dernière peut être mutualisée. Cependant, on voudra y retrouver l'organisation en contextes. Pour une base SQL, cela veut dire créer un schéma par contexte.
- Et interdiction pour un contexte d'aller lire ou écrire en base dans le schéma du petit copain. Non, on fait proprement un appel à l'API exposée par le contexte en question. Comme pour un objet, accéder directement aux données d'un contexte serait une violation de responsabilité ("tell, don't ask" ).
- Quand je dis "API", vous pouvez envisager d'invoquer réellement l'API HTTP, par opposition à des appels de fonction en mémoire. Certes, cela introduit de la latence, mais assure de passer par toutes les couches de validation des contrôleurs HTTP et facilite la transition ultérieure vers des microservices. C'est également l'opportunité d'un meilleur équilibrage de la charge lorsque vous déployez plusieurs instances applicatives du même monolithe.
Cela dit, nous avons fait l'hypothèse jusqu'à présent que les contextes communiquaient par appels directs les uns aux autres. Je vous déconseille de faire cela, car le passage en microservices, s'il devait arriver un jour, serait franchement douloureux. Que faire alors ?
Quid de la communication entre contextes ?
La modalité de déploiement ne dit rien de la modalité de communication entre contextes. De même que s'ils étaient déployés en tant que microservices, vous pouvez passer par un orchestrateur (point focal connaissant tous les contextes) ou bien souhaiter une communication événementielle, via un bus de données, pour un meilleur découplage entre contextes.
Ainsi, dans une Event-Driven Architecture, chaque contexte écoute et enregistre les informations qui lui seront utiles pour ses futurs traitements. Ultérieurement, lorsqu'il est interrogé au travers de son API, le contexte dispose de toute l'information nécessaire pour travailler en toute autonomie, que les autres contextes soient opérationnels ou non (dans le cas de microservices). Les seuls appels qu'il fera concernent des services, tels la génération d'un PDF ou l'envoi d'un mail. Et ce contexte émet à son tour de nouveaux événements, relatifs à sa seule responsabilité. On parle de chorégraphie et parfois de "cascade" événementielle quand on observe les réactions en chaîne entre contextes.
Cette modalité comporte elle aussi ses difficultés, puisqu'il faut gérer les transactions (et donc le rollback) à grande échelle. Mais d'expérience, elle est bénéfique même pour des systèmes de taille moyenne (quelques dizaines de contextes).