{"id":15008,"date":"2023-01-12T00:00:00","date_gmt":"2023-01-12T00:00:00","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/reconstruction-de-l-application-mailgun-partie-une\/"},"modified":"2026-07-24T03:43:31","modified_gmt":"2026-07-24T03:43:31","slug":"reconstruction-de-l-application-mailgun-partie-une","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/","title":{"rendered":"Analyse approfondie de la refonte de l&rsquo;application Mailgun : Partie 1 &#8211; Excellentes id\u00e9es"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Salutations, chers d\u00e9veloppeurs. Nous sommes ravis d&rsquo;annoncer qu&rsquo;apr\u00e8s trois longues ann\u00e9es de planification, de conception et de construction, notre \u00e9quipe a publi\u00e9 notre fantastique mise \u00e0 jour de l&rsquo;application. Certes, nous avons travaill\u00e9 sans rel\u00e2che pour mettre \u00e0 jour l&rsquo;apparence et l&rsquo;ergonomie de notre interface utilisateur, mais nous avons effectu\u00e9 une refonte encore plus audacieuse de <!-- -->notre pile technologique fondamentale<!-- -->.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comment cela se traduit-il pour vous\u00a0? De meilleures performances, une meilleure interface, et \u00e9volutive pour la croissance future. Nous remontons le temps pour vous pr\u00e9senter le rapport complet sur la fa\u00e7on dont nous y sommes parvenus. Rejoignez-nous pour l&rsquo;aventure.<\/p>\n\n\n\r\n    <nav data-content-type=\"longform\" class=\"toc-block longform-spacings px-5 py-6 px-md-6 px-lg-7 py-md-7 bg-light fs-sm rounded-lg\" aria-labelledby=\"toc-title-8071\"><p class=\"h5 m-0\" id=\"toc-title-8071\">Table of contents<\/p><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">01<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#pourquoi-nous-nous-sommes-lances-dans-cette-aventure\">Pourquoi nous nous sommes lanc\u00e9s dans cette aventure<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">02<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#ce-que-nous-voulions-construire\">Ce que nous voulions construire<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">03<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#historique-notre-pile-front-end-dorigine\">Historique : Notre pile front-end d&rsquo;origine<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">04<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#comment-notre-framework-herite-a-freine-notre-evolutivite\">Comment notre framework h\u00e9rit\u00e9 a frein\u00e9 notre \u00e9volutivit\u00e9<\/a><a class=\"scrollme link-body-color\" href=\"#le-probleme-de-la-gestion-des-etats-a-lechelle-de-lapplication\">Le probl\u00e8me de la gestion des \u00e9tats \u00e0 l&rsquo;\u00e9chelle de l&rsquo;application<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">05<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#limitations-du-polyrepo\">Limitations du polyrepo<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">06<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#projets-pour-un-tout-nouveau-referentiel-une-approche-modulaire\">Projets pour un tout nouveau r\u00e9f\u00e9rentiel : une approche modulaire<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">07<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#se-marcher-sur-les-pieds-la-danse-du-deploiement\">Se marcher sur les pieds : La danse du d\u00e9ploiement<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">08<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#defis-absurdes-et-solutions-excellentes\">D\u00e9fis absurdes et solutions excellentes<\/a><a class=\"scrollme link-body-color\" href=\"#ne-pas-jeter-le-bebe-avec-leau-du-bain\">Ne pas jeter le b\u00e9b\u00e9 avec l&rsquo;eau du bain<\/a><\/div><\/div><div class=\"d-flex mt-3\"><div class=\"w-auto fw-bold text-accent d-flex me-2\">09<\/div><div class=\"d-flex flex-column\"><a class=\"fw-bold scrollme link-body-color text-accent\" href=\"#nous-avons-un-plan-mais-pouvons-nous-le-concretiser\">Nous avons un plan, mais pouvons-nous le concr\u00e9tiser ?<\/a><\/div><\/div><\/nav>\n\n\n<h2 class=\"wp-block-heading\">Pourquoi nous nous sommes lanc\u00e9s dans cette aventure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mais attendez ! Avant de remonter le temps, il est important de pr\u00e9senter notre application am\u00e9lior\u00e9e. \u00ab Am\u00e9lior\u00e9e \u00bb est un euph\u00e9misme. Cela peut vous surprendre d&rsquo;apprendre que ce lifting de l&rsquo;interface utilisateur et des performances n&rsquo;\u00e9tait pas un moteur de revenus. Alors, pourquoi l&rsquo;avons-nous fait ?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Deux raisons :<\/b><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>L&rsquo;exp\u00e9rience utilisateur, telle qu&rsquo;elle existait, freinait les performances des clients envoyant de plus gros volumes d&#8217;emails et rendait difficile la navigation entre les produits de notre portefeuille en pleine croissance. Si ce n&rsquo;est pas facile \u00e0 utiliser, alors <i>vous<\/i> ne l&rsquo;utiliserez pas. <\/li>\n\n\n\n<li>Nous devions r\u00e9\u00e9valuer notre flux de donn\u00e9es API principal pour qu&rsquo;il soit davantage ax\u00e9 sur les performances et plus \u00e9volutif.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Ce que nous avons cr\u00e9\u00e9 est <b>Portail<\/b>, une interface \u00e9pique pour mieux vous connecter \u00e0 vos produits et outils de d\u00e9livrabilit\u00e9 d\u00e8s maintenant, <i>et<\/i> \u00e0 mesure que nous \u00e9voluons. <b>Portail<\/b> vous permet de naviguer entre Mailgun et nos <a href=\"https:\/\/www.mailgun.com\/fr\/products\/inbox\/inboxready\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Mailgun Optimize<\/a> produits avec facilit\u00e9 et offre une exp\u00e9rience tr\u00e8s performante \u00e0 nos utilisateurs avanc\u00e9s qui envoient des dizaines de milliers d&#8217;emails par jour.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Alors, restez avec nous pendant que nous jouons les geeks, nous concentrons et parcourons les trois derni\u00e8res ann\u00e9es de notre processus de d\u00e9veloppement.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4049\" width=\"1280\" height=\"720\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/bill-teds-excellent-adventure-wallpaper-12__1_.png\" alt=\"bill-teds-excellent-adventure-wallpaper-12__1_\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/bill-teds-excellent-adventure-wallpaper-12__1_.png 1280w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/bill-teds-excellent-adventure-wallpaper-12__1_-300x169.png 300w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/bill-teds-excellent-adventure-wallpaper-12__1_-768x432.png 768w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/bill-teds-excellent-adventure-wallpaper-12__1_-1024x576.png 1024w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Ce que nous voulions construire<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nous avons commenc\u00e9 par cr\u00e9er une liste exhaustive de toutes les diff\u00e9rentes choses que nous voulions \u2013 cela allait de la mise \u00e0 jour de la structure de notre r\u00e9f\u00e9rentiel \u00e0 la mise en \u0153uvre d&rsquo;un nouveau syst\u00e8me de d\u00e9ploiement, et nous savions que nous allions devoir le cr\u00e9er de toutes pi\u00e8ces, notre \u00e9quipe SRE migrant d&rsquo;AWS vers Google Cloud. Nous voulions \u00e9galement nous \u00e9loigner de notre conception monolithique \u00e9troitement coupl\u00e9e pour aller vers une conception plus distribu\u00e9e. Cela faciliterait tout pour l&rsquo;\u00e9quipe \u00e0 l&rsquo;avenir : du d\u00e9veloppement de tests exhaustifs au ciblage de reconstructions sans avoir besoin de se plonger dans tout le code ou de le modifier.<\/p>\n\n\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> \u00ab Que voulons-nous construire au final ? \u00bb C&rsquo;\u00e9tait la premi\u00e8re question \u00e0 laquelle nous devions r\u00e9pondre. La question suivante \u00e9tait : \u00ab Quelles sont nos lacunes ? \u00bb<\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\"><b>Lors de toute refonte, nous voulons toujours prendre en compte l&rsquo;utilisateur, mais une grande partie de la motivation derri\u00e8re la mise \u00e0 jour de notre application \u00e9tait \u00e9galement d&rsquo;am\u00e9liorer l&rsquo;exp\u00e9rience d\u00e9veloppeur. <\/b>Notre objectif \u00e9tait d&rsquo;am\u00e9liorer l&rsquo;exp\u00e9rience d\u00e9veloppeur en r\u00e9duisant consid\u00e9rablement la complexit\u00e9 de l&rsquo;obtention des donn\u00e9es de l&rsquo;API vers la page rendue, et d&rsquo;am\u00e9liorer la maintenabilit\u00e9 en r\u00e9duisant le nombre total de mod\u00e8les dans notre bo\u00eete \u00e0 outils.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Historique : Notre pile front-end d&rsquo;origine<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Les piles technologiques peuvent devenir obsol\u00e8tes, et notre pile front-end d&rsquo;origine a \u00e9t\u00e9 construite il y a pr\u00e8s d&rsquo;une d\u00e9cennie<\/b> \u2013 ce qui correspond \u00e0 350 ann\u00e9es internet. Elle comprenait un serveur web Python Flask qui g\u00e9rait probablement plus de t\u00e2ches qu&rsquo;il n&rsquo;aurait d\u00fb et dont l&rsquo;\u00e9tat \u00e9tait tr\u00e8s \u00e9troitement coupl\u00e9 et partag\u00e9 avec le client. Elle utilisait plusieurs couches d&rsquo;abstraction, initialement pr\u00e9vues pour faciliter l&rsquo;obtention de donn\u00e9es \u00e0 partir de nos API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 mesure que cette surface devenait de plus en plus grande, les mod\u00e8les apportaient plus de surcharge que de commodit\u00e9. Il est devenu tr\u00e8s difficile d&rsquo;apporter des modifications fondamentales car de nombreux endroits pouvaient \u00eatre impact\u00e9s. \u00c0 ce stade, notre client front-end \u00e9tait devenu un mus\u00e9e de mod\u00e8les React obsol\u00e8tes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Toutes nos interactions avec nos propres API publiques et priv\u00e9es \u00e9taient obscurcies par de multiples couches de complexit\u00e9s de code excessives. Cela a cr\u00e9\u00e9 un gouffre g\u00e9ant entre les d\u00e9veloppeurs front-end de Mailgun et leur compr\u00e9hension de nos API et de nos exp\u00e9riences client.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Comment notre framework h\u00e9rit\u00e9 a frein\u00e9 notre \u00e9volutivit\u00e9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Le bricolage des abstractions d&rsquo;API a non seulement entra\u00een\u00e9 une complexit\u00e9 excessive, mais a consid\u00e9rablement inhib\u00e9 notre capacit\u00e9 \u00e0 faire \u00e9voluer notre application. Nous savions que nous voulions \u00e0 terme int\u00e9grer de plus en plus de produits dans la base de code. Nous devions repenser totalement la fa\u00e7on dont nous consommions nos donn\u00e9es.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lorsque nous planifiions le nouveau framework, nous savions que nous voulions pouvoir effectuer des requ\u00eates API directement du client vers les API publiques avec le moins de middleware possible. Pourquoi\u00a0? De cette fa\u00e7on, nous pourrions comprendre et consommer nos API de la m\u00eame mani\u00e8re que nos clients le font en \u00ab mangeant notre propre nourriture pour chien \u00bb comme on dit. Je ne sais pas pour vous, mais je pr\u00e9f\u00e8re manger un steak que de la nourriture pour chien.<\/p>\n\n\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> <b>Une note du futur : <\/b>Faire des requ\u00eates API directement depuis le client vers les API publiques est un objectif \u00e0 long terme, car bon nombre des API avec lesquelles notre application web interagit sont encore priv\u00e9es. Nous pr\u00e9voyons de d\u00e9placer progressivement la plupart de ces services vers l&rsquo;espace public afin d&rsquo;avoir une interface API uniforme pour Portail.<\/div>\r\n    <\/div>\r\n\n\n\n<h3 class=\"wp-block-heading\">Le probl\u00e8me de la gestion des \u00e9tats \u00e0 l&rsquo;\u00e9chelle de l&rsquo;application<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Un autre changement important que nous voulions apporter \u00e9tait de remplacer Redux, qui g\u00e9rait l&rsquo;\u00e9tat de notre application (environ 150 \u00e9tats). Chaque \u00e9tat correspondait \u00e0 un appel r\u00e9seau, ou \u00e0 un r\u00e9seau de transformations de donn\u00e9es, et notre structure existante n&rsquo;\u00e9tablissait pas vraiment de directives sur la fa\u00e7on de l&rsquo;utiliser. Le r\u00e9sultat\u00a0? Beaucoup de redondances.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lorsqu&rsquo;un d\u00e9veloppeur introduisait un appel pour manipuler des donn\u00e9es, il devait s&rsquo;int\u00e9grer \u00e0 travers trois niveaux d&rsquo;abstraction. De plus, nous avions nos propres clients personnalis\u00e9s pour notre navigateur et notre serveur Flask (qui s&rsquo;interfa\u00e7aient avec toutes nos API). Ainsi, <b>pour qu&rsquo;un d\u00e9veloppeur ajoute une nouvelle fonctionnalit\u00e9, il devait traverser environ sept niveaux d&rsquo;abstraction au total<\/b>, et des bugs sont possibles \u00e0 n&rsquo;importe quel niveau.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ce que nous avons finalement d\u00e9couvert, c&rsquo;est que 95 % de l&rsquo;\u00e9tat de notre application n&rsquo;\u00e9tait qu&rsquo;un cache r\u00e9seau glorifi\u00e9. Sauf que nous ne tirions m\u00eame pas parti des donn\u00e9es en cache, faisant souvent des appels redondants pour demander des donn\u00e9es que nous avions d\u00e9j\u00e0, provoquant des couches imbriqu\u00e9es de rendus inutiles dans nos composants de vue. Voil\u00e0 qui s&rsquo;appelle un parcours chaotique.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cette d\u00e9composition du syst\u00e8me explique les choses un peu plus clairement, et bien que nous ne dirions jamais de mal de nos origines\u2026 une image <i>fac\u00e9tieuse<\/i> vaut mille mots.<\/p>\n\n\n<div class=\"chart longform-spacings d-flex flex-column gap-3\">\r\n    <div class=\"rounded-lg bg-light-subtle position-relative py-5 py-md-6 py-lg-7 px-3 px-md-4\">\r\n\r\n                    <p class=\"mb-4 fs-sm fw-bold text-accent text-center\">\r\n                Syst\u00e8me actuel            <\/p>\r\n        \r\n                                <div class=\"d-flex gap-4 flex-column\">\r\n                <div class=\"auto-chart\"  data-chart-type=\"bar\" data-chart-percentage=\"true\" data-chart-track=\"true\" data-chart-max=\"100\" data-chart-color=\"#f99b93\" data-chart-values=\"[&quot;61&quot;,&quot;54&quot;,&quot;31&quot;,&quot;88&quot;]\" data-chart-colors=\"[&quot;#FFBE3C&quot;,&quot;#FFBE3C&quot;,&quot;#FFBE3C&quot;,&quot;#FFBE3C&quot;]\" data-chart-titles=\"[&quot;Complexe&quot;,&quot;Lent&quot;,&quot;Fastidieux&quot;,&quot;Nul&quot;]\" data-chart-series=\"[]\"><\/div>\r\n\r\n                            <\/div>\r\n            \r\n        \r\n        \r\n    <\/div>\r\n    <\/div>\n\n\n<p class=\"wp-block-paragraph\">Notre \u00e9quipe est le genre d&rsquo;\u00e9quipe qui s&rsquo;appuie sur elle-m\u00eame et it\u00e8re, mais pour cette refonte de l&rsquo;application, nous avons d\u00fb revenir en arri\u00e8re et retravailler certains composants fondamentaux de notre infrastructure \u2013 en commen\u00e7ant par le contr\u00f4le du code source.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations du polyrepo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Un <\/b><a href=\"https:\/\/github.com\/joelparkerhenderson\/monorepo-vs-polyrepo\" target=\"_tabs\" rel=\"noopener noreferrer\"><b>polyrepo<\/b><\/a><b> est un r\u00e9f\u00e9rentiel qui contient plusieurs projets. <\/b>Nous avons utilis\u00e9 un style d&rsquo;organisation polyrepo, ce qui signifie simplement que chaque projet front-end avait son propre r\u00e9f\u00e9rentiel, m\u00eame si plusieurs projets r\u00e9p\u00e9taient les m\u00eames t\u00e2ches et reproduisaient les m\u00eames fonctionnalit\u00e9s. En tant que hub central, les polyrepos peuvent devenir un d\u00e9fi \u00e0 maintenir \u00e0 mesure que le nombre de projets stock\u00e9s augmente. Dans de nombreux cas, nous devions d\u00e9ployer chaque polyrepo simultan\u00e9ment avec les m\u00eames mises \u00e0 jour pour garantir une exp\u00e9rience coh\u00e9rente sur l&rsquo;ensemble de nos produits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">D&rsquo;un point de vue de la maintenance, cela a rendu difficile pour les \u00e9quipes de localiser et de travailler avec le code dont elles ont besoin. G\u00e9rer plusieurs r\u00e9f\u00e9rentiels avec des fonctionnalit\u00e9s redondantes signifie g\u00e9n\u00e9ralement qu&rsquo;ils sont plus lents \u00e0 r\u00e9pondre <i>et<\/i> plus gourmands en ressources, ce qui est un gros probl\u00e8me si vous poussez et tirez fr\u00e9quemment du code. Parce que les fonctionnalit\u00e9s peuvent \u00eatre distribu\u00e9es sur plusieurs bases de code, les polyrepos peuvent rendre la recherche de bugs plus difficile que de trouver la proverbiale aiguille dans une botte de foin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Avec notre structure polyrepo d&rsquo;avant la refonte, nous savions que l&rsquo;avenir serait une r\u00e9alit\u00e9 o\u00f9 nous devrions fouiller dans les r\u00e9f\u00e9rentiels avec une lampe de poche pour chercher ce dont nous avions besoin, et qu&rsquo;il serait difficile de collaborer, d&rsquo;\u00e9voluer et de partager du code \u00e0 mesure de notre croissance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Voici nos principales pr\u00e9occupations :<\/b><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Co-d\u00e9veloppement difficile<\/li>\n\n\n\n<li>Couplage \u00e9troit<\/li>\n\n\n\n<li>Gestion de l&rsquo;\u00e9volutivit\u00e9, de la disponibilit\u00e9 et des performances<\/li>\n\n\n\n<li>Difficult\u00e9 \u00e0 partager du code<\/li>\n\n\n\n<li>Duplication<\/li>\n\n\n\n<li>Outillage incoh\u00e9rent<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En ce qui concerne la gestion du code source, il existe de nombreuses solutions, mais nous avons d\u00e9cid\u00e9 qu&rsquo;une structure modulaire et monorepo soulagerait la majorit\u00e9 de nos difficult\u00e9s de d\u00e9veloppement \u00e0 l&rsquo;avenir.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Projets pour un tout nouveau r\u00e9f\u00e9rentiel : une approche modulaire<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Une approche monorepo implique de stocker tout le code du projet dans un seul et grand r\u00e9f\u00e9rentiel<\/b>. Cela r\u00e9soudrait les probl\u00e8mes de partage de code et de duplication que nous avons rencontr\u00e9s avec notre organisation polyrepo, mais les monorepos ne sont pas une solution miracle. Si le code est \u00e9troitement coupl\u00e9, les monorepos doivent \u00e9galement \u00eatre con\u00e7us avec modularit\u00e9.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Une approche modulaire consiste \u00e0 diviser un vaste projet en modules plus petits et ind\u00e9pendants qui peuvent \u00eatre d\u00e9velopp\u00e9s, test\u00e9s et maintenus s\u00e9par\u00e9ment<\/b>. Cela permet une plus grande flexibilit\u00e9 et r\u00e9utilisabilit\u00e9, ainsi que la capacit\u00e9 de mettre \u00e0 jour facilement des modules individuels sans affecter le reste du projet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nous savions qu&rsquo;une solution modulaire de type monorepo nous permettrait d&rsquo;\u00eatre plus efficaces avec :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>G\u00e9n\u00e9ration de code<\/li>\n\n\n\n<li>Partage de code<\/li>\n\n\n\n<li>Ex\u00e9cution et orchestration de t\u00e2ches distribu\u00e9es<\/li>\n\n\n\n<li>Mise en cache<\/li>\n\n\n\n<li>TypeScript<\/li>\n<\/ul>\n\n\n    <div data-content-type=\"longform\"  class=\"callout text-body-color px-5 py-6 px-md-6 px-lg-7 py-md-7 longform-spacings rounded-lg bg-light\" data-theme=\"light\">\r\n\r\n        <div class=\"content-body\"> <b>TypeScript est un surensemble de JavaScript typ\u00e9 qui permet aux d\u00e9veloppeurs de cr\u00e9er plus facilement des projets \u00e0 grande \u00e9chelle.<\/b> Il am\u00e9liore l&rsquo;exp\u00e9rience d\u00e9veloppeur en fournissant des interfaces, des alias de type, une analyse statique de code au moment du d\u00e9veloppement et d&rsquo;autres outils tout en permettant aux d\u00e9veloppeurs d&rsquo;ajouter du typage \u00e0 leurs projets. Pour notre \u00e9quipe, TypeScript est une comp\u00e9tence que nous savions vouloir commencer \u00e0 rechercher lorsqu&rsquo;il s&rsquo;agissait d&rsquo;ajouter des membres \u00e0 notre \u00e9quipe.<\/div>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">Se marcher sur les pieds : La danse du d\u00e9ploiement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ind\u00e9niablement, le plus grand d\u00e9fi de vivre dans un monorepo (monolithique ou autre) est que plus il y a de contributeurs, plus le risque de se marcher sur les pieds est grand. \u00c0 quoi sert une exp\u00e9rience d\u00e9veloppeur remani\u00e9e si votre code est \u00e9cras\u00e9 lors d&rsquo;une mauvaise fusion ? Si nous proc\u00e9dons vraiment \u00e0 une refonte holistique de notre pile, alors nous devons \u00e9galement examiner comment nous pouvons am\u00e9liorer notre processus de d\u00e9ploiement. Voici les d\u00e9fis les plus urgents :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><b>\u00c9volutivit\u00e9 : <\/b>Ce serait une mauvaise id\u00e9e de reconstruire TOUT le code du monorepo pour les plus petits changements, disons, corriger une faute de frappe dans un texte. C&rsquo;est exactement ce que nous faisions dans notre ancien syst\u00e8me. Le nouveau processus tirerait parti des capacit\u00e9s int\u00e9gr\u00e9es de NX pour \u00e9valuer et reconstruire uniquement les fichiers affect\u00e9s par la modification, au niveau le plus granulaire.<\/li>\n\n\n\n<li><b>D\u00e9ploiement : <\/b>Nous avons conserv\u00e9 la plupart des \u00e9l\u00e9ments de notre pipeline de d\u00e9ploiement. Une fois l&rsquo;image construite, elle atterrit dans le r\u00e9f\u00e9rentiel de conteneurs GitHub. Notre \u00e9quipe SRE a peaufin\u00e9 notre syst\u00e8me de d\u00e9ploiement lors de la migration d&rsquo;AWS vers GCP. Nous pouvons facilement d\u00e9ployer n&rsquo;importe quelle branche depuis notre canal de d\u00e9ploiement Slack, avec de meilleurs rapports gr\u00e2ce \u00e0 un ajout r\u00e9cent que nous avons obtenu pendant la migration.<\/li>\n\n\n\n<li><b>CI\/CD :<\/b> Notre ancien syst\u00e8me utilisait une tr\u00e8s ancienne version de Jenkins pour ex\u00e9cuter les tests et construire\/distribuer les images de notre application derri\u00e8re un VPN. Lorsque le build \u00e9chouait, nous avions besoin d&rsquo;un d\u00e9veloppeur senior haut plac\u00e9, familiaris\u00e9 avec les anciennes m\u00e9thodes, pour le corriger. Dans notre nouveau syst\u00e8me, nous avons pr\u00e9vu de passer \u00e0 GitHub Actions, o\u00f9 les configurations sont accessibles, d\u00e9claratives et bien document\u00e9es.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">D\u00e9fis absurdes et solutions excellentes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les projets de toutes sortes comportent des d\u00e9fis, certains attendus et d&rsquo;autres surprenants. Nous savions que nous devions planifier pour surmonter certains probl\u00e8mes et que la nouvelle version de l&rsquo;application devait se concentrer sur les performances sous de multiples angles.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Probl\u00e8mes identifi\u00e9s<\/th><th>Solutions propos\u00e9es<\/th><\/tr><\/thead><tbody><tr><td><strong>Conventions de code peu claires<\/strong><br>Les conventions de code font r\u00e9f\u00e9rence \u00e0 l&rsquo;ensemble des styles de codage, des solutions et des mod\u00e8les r\u00e9utilisables au sein d&rsquo;une base de code. Imaginez une \u00e9quipe de charpentiers travaillant sur un projet. S&rsquo;ils gardent 1 000 outils sp\u00e9cialis\u00e9s sur le chantier, il est probable qu&rsquo;un travailleur choisisse le mauvais outil pour la t\u00e2che ou l&rsquo;utilise de mani\u00e8re inappropri\u00e9e. Et contrairement aux outils physiques, les d\u00e9pendances logicielles peuvent devenir obsol\u00e8tes, emp\u00eachant ainsi les futures mises \u00e0 jour de la base de code.<\/td><td><strong>Guide de style de code<\/strong><br>Le maintien de guides de style de codage explicites\u00a0et d&rsquo;un ensemble minimal de mod\u00e8les simples et puissants aide \u00e0 r\u00e9duire la redondance, les incoh\u00e9rences et la complexit\u00e9, et peut m\u00eame entra\u00eener une am\u00e9lioration des performances. La r\u00e9utilisation d&rsquo;un petit ensemble de solutions et de mod\u00e8les g\u00e9n\u00e9ralis\u00e9s rend le code plus facile \u00e0 comprendre et r\u00e9duit la probabilit\u00e9 de bugs difficiles \u00e0 trouver.<\/td><\/tr><tr><td><strong>\u00c9tat surcharg\u00e9<\/strong><br>Nous avons utilis\u00e9 Redux comme solution universelle pour l&rsquo;\u00e9tat global de l&rsquo;application. Cependant, 90 % de notre store Redux n&rsquo;\u00e9tait qu&rsquo;une simple mise en cache r\u00e9seau glorifi\u00e9e. Redux n\u00e9cessite de multiples couches de surcharge pour chaque membre de l&rsquo;\u00e9tat. Cela a entra\u00een\u00e9 de nombreuses redondances et une complexit\u00e9 inutile.<\/td><td><strong>S\u00e9parer le cache r\u00e9seau et l&rsquo;\u00e9tat de l&rsquo;application<\/strong><br>La s\u00e9paration des fonctionnalit\u00e9s du cache r\u00e9seau de l&rsquo;\u00e9tat de l&rsquo;application nous permet de conserver une empreinte d&rsquo;\u00e9tat beaucoup plus petite. L&rsquo;\u00e9tat peut \u00eatre mis en \u0153uvre de mani\u00e8re plus locale. La r\u00e9duction de la surcharge se traduit par une augmentation des performances et donne aux d\u00e9veloppeurs plus de contr\u00f4le sur la fa\u00e7on dont les donn\u00e9es sont utilis\u00e9es.<br>Nous avons choisi React Query\u00a0comme interface avec nos API backend, ce qui nous permet de g\u00e9rer facilement les donn\u00e9es de mani\u00e8re asynchrone et de r\u00e9duire la surcharge r\u00e9seau.<\/td><\/tr><tr><td><strong>Architecture r\u00e9seau multicouche<\/strong><br>Notre application s&rsquo;est d\u00e9velopp\u00e9e de mani\u00e8re organique, passant d&rsquo;un panneau de contr\u00f4le de base centr\u00e9 sur l&rsquo;API \u00e0 la suite multi-produits d&rsquo;outils client que nous avons aujourd&rsquo;hui. Initialement, le client \u00e9tait construit sur un outillage Python commun partag\u00e9 par plusieurs de nos backends d&rsquo;API. Cela conduit \u00e0 avoir de nombreuses couches de middleware n\u00e9cessaires pour le moindre appel API, m\u00eame le plus simple. Non seulement cela rendait difficile la compr\u00e9hension de l&rsquo;origine d&rsquo;une donn\u00e9e donn\u00e9e, mais cela rendait \u00e9galement l&rsquo;identification des bugs dans la pile r\u00e9seau tr\u00e8s chronophage.<\/td><td><strong>L&rsquo;API publique d&rsquo;abord<\/strong><br>Plut\u00f4t que de faire passer les requ\u00eates via de multiples proxys, couches d&rsquo;authentification et interfaces Python, nous avons d\u00e9cid\u00e9 tr\u00e8s t\u00f4t que, dans tous les cas possibles, nous collecterions les donn\u00e9es n\u00e9cessaires directement depuis le client en utilisant les API publiquement disponibles. Cela a non seulement consid\u00e9rablement r\u00e9duit nos frais g\u00e9n\u00e9raux et notre complexit\u00e9, mais cela nous a \u00e9galement aid\u00e9s \u00e0 mieux percevoir nos services API du point de vue de nos clients. Nous avons l&rsquo;intention de pousser cette initiative plus loin dans un avenir proche, en rendant davantage de nos API publiques.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Ne pas jeter le b\u00e9b\u00e9 avec l&rsquo;eau du bain<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nous avons \u00e9crit des centaines de milliers de lignes de code au cours de la derni\u00e8re d\u00e9cennie. Avec l&rsquo;ampleur et la port\u00e9e de ce nouveau projet, il faudrait presque autant d&rsquo;ann\u00e9es pour porter et r\u00e9\u00e9crire nos anciennes fonctionnalit\u00e9s dans le nouveau paradigme. Ce serait un \u00e9chec d&#8217;embl\u00e9e. Nous devions trouver un moyen de continuer \u00e0 int\u00e9grer ces fonctionnalit\u00e9s existantes sans compromettre nos objectifs pour la nouvelle pile. Nous avons trouv\u00e9 une solution dans une technologie appel\u00e9e f\u00e9d\u00e9ration de modules (module federation).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gr\u00e2ce au plugin de f\u00e9d\u00e9ration de modules de Webpack, nous avons pu <b>cr\u00e9er un nouveau build de notre ancienne application avec des modifications minimes<\/b>, ce qui permettrait d&rsquo;int\u00e9grer les fonctionnalit\u00e9s existantes dans la nouvelle pile Portail. Nous aurions toujours pour objectif \u00e0 long terme de porter le code d\u00e9sormais h\u00e9rit\u00e9 vers des normes plus r\u00e9centes, mais cela nous permettrait de commencer \u00e0 \u00e9crire imm\u00e9diatement de nouvelles fonctionnalit\u00e9s avec les nouveaux avantages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nous avons un plan, mais pouvons-nous le concr\u00e9tiser ?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nous savions que consolider nos plateformes tout en d\u00e9veloppant continuellement les fonctionnalit\u00e9s et les ensembles de produits n\u00e9cessiterait un effort massif, et notre planification a influenc\u00e9 ce que nous voulions pour notre nouvelle pile front-end, ainsi que la mani\u00e8re dont nous allions g\u00e9rer l&rsquo;h\u00e9ritage persistant des syst\u00e8mes de style CSS obsol\u00e8tes, des mod\u00e8les de composants de classe d\u00e9pr\u00e9ci\u00e9s et d&rsquo;une gestion maladroite de l&rsquo;\u00e9tat de l&rsquo;application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Parce que nous repartions de z\u00e9ro \u2013 en particulier avec le passage d&rsquo;AWS \u00e0 Google Cloud \u2013 <b>la meilleure solution \u00e9tait une rupture nette<\/b>. Un nouveau r\u00e9f\u00e9rentiel avec de meilleures normes plus \u00e9lev\u00e9es, une f\u00e9d\u00e9ration de modules, des biblioth\u00e8ques modulaires et partag\u00e9es, et une documentation interne et orient\u00e9e utilisateur plus compl\u00e8te.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" class=\"wp-image-4052\" width=\"1440\" height=\"748\" src=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/EN-Tools-Trade.png\" alt=\"New front-end stack; Nx, React, Webpack, TypeScript, Cypress, Jest, ES Links, Prettier, and Mock Service Worker.\" srcset=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/EN-Tools-Trade.png 1440w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/EN-Tools-Trade-300x156.png 300w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/EN-Tools-Trade-768x399.png 768w, https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/EN-Tools-Trade-1024x532.png 1024w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ce fut une \u00e9tape de pr\u00e9paration et de planification intense. Comme pour tous les grands projets, la g\u00e9n\u00e9ration des id\u00e9es et de la preuve de concept a \u00e9t\u00e9 une entreprise technique et cr\u00e9ative qui n&rsquo;a impliqu\u00e9 que quelques personnes s\u00e9lectionn\u00e9es.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Phase 2 ? Transformer l&rsquo;id\u00e9e en r\u00e9alit\u00e9 \u2013 et cela a impliqu\u00e9 beaucoup plus d&rsquo;\u00e9quipes. D\u00e9veloppeurs, je crois que notre aventure est sur le point de prendre une tournure des plus int\u00e9ressantes. <\/p>\n\n\n\r\n    <aside data-content-type=\"longform\"  class=\"banner-block longform-spacings rounded-lg shadow-lg px-5 py-6 px-md-6 py-md-7 p-lg-7 bg-light\" data-theme=\"dark\" aria-labelledby=\"banner-block-block_0d9186b1ca948a38ef9200a67122829d\">\r\n                            <p class=\"h4 text-accent fw-bold\" id=\"banner-block-block_0d9186b1ca948a38ef9200a67122829d\">\r\n                D\u00e9couvrez la Partie 2 \u2013 Une ex\u00e9cution des plus triomphantes            <\/p>\r\n                            <div class=\"mb-0 text-body-color\">\r\n                                    <div class=\"content-body mb-0 text-body-color\">Dans la partie 1, nous avons r\u00e9pondu \u00e0 la question : Pourquoi reconstruire ? Dans la partie 2, nous plongeons dans la mise en \u0153uvre et l&rsquo;ex\u00e9cution. Il y a du drame, il y a des migrations&#8230; et probablement un peu trop de r\u00e9f\u00e9rences \u00e0 la science-fiction. Rejoignez-nous pour l&rsquo;aventure.<\/div>\r\n                            <\/div>\r\n        \r\n        <div class=\"text-start mt-5\"><a href=\"https:\/\/www.mailgun.com\/blog\/dev-life\/mailgun-app-rebuild-part-two\/\"  class=\"btn btn-secondary\" >Read the blog<\/a><\/div>\r\n    <\/aside>\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Salutations, chers d\u00e9veloppeurs. Nous sommes ravis d&rsquo;annoncer qu&rsquo;apr\u00e8s trois longues ann\u00e9es de planification, de conception et de construction, notre \u00e9quipe a publi\u00e9 notre fantastique mise \u00e0 jour de l&rsquo;application. Certes, nous avons travaill\u00e9 sans rel\u00e2che pour mettre \u00e0 jour l&rsquo;apparence et l&rsquo;ergonomie de notre interface utilisateur, mais nous avons effectu\u00e9 une refonte encore plus audacieuse [&hellip;]<\/p>\n","protected":false},"author":17,"featured_media":3952,"menu_order":0,"template":"","meta":{"_acf_changed":false,"footnotes":""},"blog_category":[19],"class_list":["post-15008","blog","type-blog","status-publish","has-post-thumbnail","hentry","blog_category-dev-life"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"La mise \u00e0 jour de l&#039;application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"La mise \u00e0 jour de l&#039;application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-24T03:43:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"448\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/\",\"name\":\"Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"datePublished\":\"2023-01-12T00:00:00+00:00\",\"dateModified\":\"2026-07-24T03:43:31+00:00\",\"description\":\"La mise \u00e0 jour de l'application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/MG-Blog-Dev-Life.png\",\"width\":720,\"height\":448},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/dev-life\\\/reconstruction-de-l-application-mailgun-partie-une\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Analyse approfondie de la refonte de l\u2019application Mailgun : Partie 1 \u2013 Excellentes id\u00e9es\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"description\":\"Powerful Transactional Email APIs that enable you to send, receive, and track emails, built with developers in mind. Learn more today!\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"contentUrl\":\"https:\\\/\\\/www.mailgun.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/cropped-android-chrome-512x512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Transactional Email API Service For Developers | Mailgun\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun","description":"La mise \u00e0 jour de l'application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/","og_locale":"fr_FR","og_type":"article","og_title":"Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun","og_description":"La mise \u00e0 jour de l'application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.","og_url":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","article_modified_time":"2026-07-24T03:43:31+00:00","og_image":[{"width":720,"height":448,"url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/","url":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/","name":"Comment nous avons reconstruit notre application Mailgun pour de multiples produits : Partie 1 - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/fr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/#primaryimage"},"thumbnailUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","datePublished":"2023-01-12T00:00:00+00:00","dateModified":"2026-07-24T03:43:31+00:00","description":"La mise \u00e0 jour de l'application Mailgun r\u00e9cemment publi\u00e9e a commenc\u00e9 comme une op\u00e9ration de base. Vous voulez voir comment nous y sommes parvenus ? Rejoignez-nous dans cette excellente aventure.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/#primaryimage","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/07\/MG-Blog-Dev-Life.png","width":720,"height":448},{"@type":"BreadcrumbList","@id":"https:\/\/www.mailgun.com\/fr\/blog\/dev-life\/reconstruction-de-l-application-mailgun-partie-une\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/fr\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/fr\/blog\/"},{"@type":"ListItem","position":3,"name":"Analyse approfondie de la refonte de l\u2019application Mailgun : Partie 1 \u2013 Excellentes id\u00e9es"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/fr\/#website","url":"https:\/\/www.mailgun.com\/fr\/","name":"Transactional Email API Service For Developers | Mailgun","description":"Powerful Transactional Email APIs that enable you to send, receive, and track emails, built with developers in mind. Learn more today!","publisher":{"@id":"https:\/\/www.mailgun.com\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/fr\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.mailgun.com\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","contentUrl":"https:\/\/www.mailgun.com\/wp-content\/uploads\/2025\/06\/cropped-android-chrome-512x512-1.png","width":512,"height":512,"caption":"Transactional Email API Service For Developers | Mailgun"},"image":{"@id":"https:\/\/www.mailgun.com\/fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/15008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/users\/17"}],"version-history":[{"count":2,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/15008\/revisions"}],"predecessor-version":[{"id":15038,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog\/15008\/revisions\/15038"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/media\/3952"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/media?parent=15008"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/fr\/wp-json\/wp\/v2\/blog_category?post=15008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}