{"id":15013,"date":"2023-01-12T00:00:00","date_gmt":"2023-01-12T00:00:00","guid":{"rendered":"https:\/\/www.mailgun.com\/blog\/mailgun-app-rebuild-part-one-2\/"},"modified":"2026-07-24T04:59:17","modified_gmt":"2026-07-24T04:59:17","slug":"mailgun-app-rebuild-part-one","status":"publish","type":"blog","link":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/","title":{"rendered":"Um mergulho profundo na reconstru\u00e7\u00e3o do aplicativo Mailgun: Parte 1 &#8211; Ideias excelentes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Sauda\u00e7\u00f5es, colegas desenvolvedores. Estamos empolgados em anunciar que, ap\u00f3s tr\u00eas longos anos de planejamento, design e constru\u00e7\u00e3o, nossa equipe lan\u00e7ou nossa fant\u00e1stica atualiza\u00e7\u00e3o de aplicativo. Claro, temos trabalhado incansavelmente para atualizar a apar\u00eancia de nossa interface de usu\u00e1rio, mas fizemos uma reformula\u00e7\u00e3o ainda mais ousada em <!-- -->nossa pilha de tecnologia fundamental<!-- -->.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O que isso significa para voc\u00ea? Melhor desempenho, melhor interface e escalabilidade para crescimento futuro. Estamos viajando de volta no tempo para trazer a voc\u00ea o relat\u00f3rio completo sobre como fizemos isso acontecer. Junte-se a n\u00f3s nesta jornada.<\/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-6728\"><p class=\"h5 m-0\" id=\"toc-title-6728\">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=\"#por-que-embarcamos-nesta-jornada\">Por que embarcamos nesta jornada<\/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=\"#o-que-queriamos-construir\">O que quer\u00edamos construir<\/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=\"#historia-nossa-pilha-original-de-front-end\">Hist\u00f3ria: Nossa pilha original de front-end<\/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=\"#como-nossa-estrutura-legada-prejudicou-nossa-escalabilidade\">Como nossa estrutura legada prejudicou nossa escalabilidade<\/a><a class=\"scrollme link-body-color\" href=\"#o-problema-em-gerenciar-estados-em-todo-o-aplicativo\">O problema em gerenciar estados em todo o aplicativo<\/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=\"#limitacoes-do-polyrepo\">Limita\u00e7\u00f5es do 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=\"#planos-para-um-novo-repositorio-brilhante-uma-abordagem-modular\">Planos para um novo reposit\u00f3rio brilhante: uma abordagem modular<\/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=\"#pisando-em-calos-a-danca-da-implantacao\">Pisando em calos: a dan\u00e7a da implanta\u00e7\u00e3o<\/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=\"#desafios-falsos-e-solucoes-excelentes\">Desafios falsos e solu\u00e7\u00f5es excelentes<\/a><a class=\"scrollme link-body-color\" href=\"#nao-jogue-o-bebe-fora-junto-com-a-agua-do-banho\">N\u00e3o jogue o beb\u00ea fora junto com a \u00e1gua do banho<\/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=\"#ainda-teriamos-um-objetivo-de-longo-prazo-de-portar-o-codigo-legado-para-padroes-mais-recentes-mas-isso-nos-permitiria-comecar-a-escrever-novos-recursos-com-os-novos-beneficios-imediatamente\">Ainda ter\u00edamos um objetivo de longo prazo de portar o c\u00f3digo legado para padr\u00f5es mais recentes, mas isso nos permitiria come\u00e7ar a escrever novos recursos com os novos benef\u00edcios imediatamente.<\/a><\/div><\/div><\/nav>\n\n\n<h2 class=\"wp-block-heading\">Por que embarcamos nesta jornada<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mas espere! Antes de voltarmos no tempo, \u00e9 importante apresentar nosso aplicativo melhorado. \u201cMelhorado\u201d \u00e9 um eufemismo. Pode surpreend\u00ea-lo que esta renova\u00e7\u00e3o de interface e desempenho n\u00e3o foi um impulsionador de receita. Ent\u00e3o, por que fizemos isso?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Dois motivos:<\/b><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A experi\u00eancia do usu\u00e1rio, como existia, inibia o desempenho para os clientes que enviavam grandes volumes de e-mails e tornava desafiador navegar entre os produtos de nosso crescente portf\u00f3lio. Se n\u00e3o for f\u00e1cil de usar, ent\u00e3o <i>voc\u00ea<\/i> n\u00e3o usar\u00e1. <\/li>\n\n\n\n<li>Precis\u00e1vamos reavaliar nosso fluxo de dados central da API para ser mais orientado ao desempenho e escal\u00e1vel.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">O que criamos \u00e9 o <b>portal<\/b>, uma interface \u00e9pica para conectar voc\u00ea melhor aos seus produtos e ferramentas de entregabilidade agora, <i>e<\/i> \u00e0 medida que crescemos. O <b>portal<\/b> permite que voc\u00ea alterne entre nosso Mailgun e <a href=\"https:\/\/www.mailgun.com\/pt\/products\/inbox\/inboxready\/\" target=\"_tabs\" rel=\"noopener noreferrer\">Mailgun Optimize<\/a> nossos produtos com facilidade e oferece uma experi\u00eancia de alto desempenho para nossos usu\u00e1rios avan\u00e7ados que enviam dezenas de milhares de e-mails por dia.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ent\u00e3o, fique conosco enquanto mergulhamos nos detalhes t\u00e9cnicos, nos aprofundamos e viajamos pelos \u00faltimos tr\u00eas anos de nosso processo de desenvolvimento.<\/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\">O que quer\u00edamos construir<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Come\u00e7amos criando uma longa lista de todas as coisas diferentes que quer\u00edamos \u2013 desde a atualiza\u00e7\u00e3o da estrutura do nosso reposit\u00f3rio at\u00e9 a implementa\u00e7\u00e3o de um novo sistema de implanta\u00e7\u00e3o, e sab\u00edamos que ter\u00edamos que cri\u00e1-lo do zero enquanto nossa equipe de SRE migrava da AWS para o Google Cloud. Tamb\u00e9m quer\u00edamos abandonar nosso design monol\u00edtico fortemente acoplado por um design mais distribu\u00eddo. Isso facilitaria tudo para a equipe daqui para frente: desde o desenvolvimento de testes abrangentes at\u00e9 o direcionamento de reconstru\u00e7\u00f5es sem a necessidade de vasculhar ou alterar todo o c\u00f3digo.<\/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\"> \u201cO que queremos construir no final das contas?\u201d Esta foi a primeira pergunta que tivemos que responder. A pr\u00f3xima pergunta foi: \u201cOnde estamos deixando a desejar?\u201d<\/div>\r\n    <\/div>\r\n\n\n\n<p class=\"wp-block-paragraph\"><b>Em qualquer reformula\u00e7\u00e3o, sempre queremos considerar o usu\u00e1rio, mas grande parte da motiva\u00e7\u00e3o por tr\u00e1s da atualiza\u00e7\u00e3o do nosso aplicativo tamb\u00e9m foi melhorar a experi\u00eancia do desenvolvedor. <\/b>Nosso objetivo era aprimorar a experi\u00eancia do desenvolvedor reduzindo significativamente a complexidade de obter dados da API para a p\u00e1gina renderizada, e melhorar a capacidade de manuten\u00e7\u00e3o diminuindo o n\u00famero total de padr\u00f5es em nosso conjunto de ferramentas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hist\u00f3ria: Nossa pilha original de front-end<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>As pilhas de tecnologia podem ficar desatualizadas, e nossa pilha de front-end original foi constru\u00edda h\u00e1 quase uma d\u00e9cada<\/b> \u2013 o que equivale a 350 em anos de internet. Ela inclu\u00eda um servidor web Python Flask que provavelmente lidava com mais tarefas do que deveria e tinha um estado fortemente acoplado compartilhado com o cliente. Ela usava v\u00e1rias camadas de abstra\u00e7\u00e3o, originalmente destinadas a facilitar a obten\u00e7\u00e3o de dados de nossas APIs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 medida que essa superf\u00edcie crescia cada vez mais, os padr\u00f5es forneciam mais sobrecarga do que conveni\u00eancia. Tornou-se muito dif\u00edcil fazer mudan\u00e7as fundamentais porque havia muitos lugares que poderiam ser impactados. Neste momento, nosso cliente front-end havia se tornado um museu de padr\u00f5es obsoletos do React.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Todas as nossas intera\u00e7\u00f5es com nossas pr\u00f3prias APIs p\u00fablicas e privadas foram ofuscadas por meio de m\u00faltiplas camadas de complexidades excessivas de c\u00f3digo. Isso criou um abismo gigantesco entre os desenvolvedores de front-end do Mailgun e a compreens\u00e3o deles sobre nossas APIs e as experi\u00eancias do cliente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Como nossa estrutura legada prejudicou nossa escalabilidade<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A gambiarra de abstra\u00e7\u00f5es de API n\u00e3o apenas resultou em complexidade excessiva, mas tamb\u00e9m inibiu significativamente nossa capacidade de dimensionar nosso aplicativo. Sab\u00edamos que, eventualmente, quer\u00edamos trazer cada vez mais produtos para a base de c\u00f3digo. Precisar\u00edamos repensar totalmente a forma como consum\u00edamos nossos dados.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ao fazer nosso plano para a nova estrutura, sab\u00edamos que quer\u00edamos ser capazes de fazer solicita\u00e7\u00f5es de API diretamente do cliente para as APIs p\u00fablicas com o m\u00ednimo de middleware poss\u00edvel. Por qu\u00ea? Desta forma, ser\u00edamos capazes de entender e consumir nossas APIs da mesma forma que nossos clientes fazem, \u201ccomendo nossa pr\u00f3pria ra\u00e7\u00e3o\u201d (eating our own dog food), como dizem. Eu n\u00e3o sei quanto a voc\u00ea, mas prefiro comer bife a comida de cachorro.<\/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>Uma nota do futuro: <\/b>Fazer solicita\u00e7\u00f5es de API diretamente do cliente para as APIs p\u00fablicas \u00e9 um objetivo a longo prazo, j\u00e1 que muitas das APIs com as quais nosso aplicativo web se comunica ainda s\u00e3o privadas. Temos o plano de mover gradualmente a maioria desses servi\u00e7os para o espa\u00e7o p\u00fablico, a fim de ter uma interface de API uniforme para o portal.<\/div>\r\n    <\/div>\r\n\n\n\n<h3 class=\"wp-block-heading\">O problema em gerenciar estados em todo o aplicativo<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Outra mudan\u00e7a significativa que quer\u00edamos fazer era substituir o Redux, que gerenciava o estado de todo o nosso aplicativo (cerca de 150 estados). Cada estado era mapeado para uma chamada de rede, ou rede de transforma\u00e7\u00f5es de dados, e nossa estrutura legada n\u00e3o estabelecia diretrizes reais sobre como us\u00e1-lo. O resultado? Muitas redund\u00e2ncias.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quando um desenvolvedor introduzia uma chamada para manipular dados, ele a integrava atrav\u00e9s de tr\u00eas n\u00edveis de abstra\u00e7\u00e3o. Al\u00e9m disso, t\u00ednhamos nossos pr\u00f3prios clientes personalizados para nosso navegador e nosso servidor Flask (que interagia com todas as nossas APIs). Portanto, <b>para um desenvolvedor adicionar um novo recurso, ele teria que passar por cerca de sete n\u00edveis totais de abstra\u00e7\u00e3o<\/b>, e os bugs s\u00e3o poss\u00edveis em qualquer n\u00edvel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O que acabamos descobrindo foi que 95% do estado de todo o aplicativo era apenas um cache de rede glorificado. S\u00f3 que n\u00e3o est\u00e1vamos nem colhendo os benef\u00edcios dos dados em cache, muitas vezes fazendo chamadas redundantes para solicitar dados que j\u00e1 t\u00ednhamos, causando camadas aninhadas de re-renderiza\u00e7\u00f5es desnecess\u00e1rias em nossos componentes de visualiza\u00e7\u00e3o. Isso que \u00e9 uma jornada acidentada.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Este detalhamento do sistema explica as coisas com um pouco mais de clareza e, embora nunca fal\u00e1ssemos mal de nossas origens&#8230; uma imagem <i>jocosa<\/i> vale mais que mil palavras.<\/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                Sistema atual            <\/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;Complexo&quot;,&quot;Lento&quot;,&quot;Tedioso&quot;,&quot;P\\u00e9ssimo&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\">Nossa equipe \u00e9 o tipo de equipe que evolui e itera, mas para essa reconstru\u00e7\u00e3o do aplicativo, tivemos que voltar atr\u00e1s e refazer alguns componentes fundamentais de nossa infraestrutura \u2013 come\u00e7ando pelo controle de c\u00f3digo-fonte.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Limita\u00e7\u00f5es do polyrepo<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Um <\/b><a href=\"https:\/\/github.com\/joelparkerhenderson\/monorepo-vs-polyrepo\" target=\"_tabs\" rel=\"noopener noreferrer\"><b>polyrepo<\/b><\/a><b> \u00e9 um reposit\u00f3rio que cont\u00e9m v\u00e1rios projetos. <\/b>N\u00f3s usamos um estilo de organiza\u00e7\u00e3o polyrepo, o que significa apenas que cada projeto de front-end tinha seu pr\u00f3prio reposit\u00f3rio, embora muitos dos projetos repetissem as mesmas tarefas e reproduzissem os mesmos recursos. Como um hub central, os polyrepos podem se tornar um desafio de manter \u00e0 medida que o n\u00famero de projetos armazenados aumenta. Em muitos casos, tivemos que implantar cada polyrepo simultaneamente com as mesmas atualiza\u00e7\u00f5es para garantir uma experi\u00eancia consistente em nossos produtos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do ponto de vista da manuten\u00e7\u00e3o, isso dificultou que as equipes localizassem e trabalhassem com o c\u00f3digo de que precisam. O gerenciamento de v\u00e1rios reposit\u00f3rios com recursos redundantes geralmente significa que eles respondem mais lentamente <i>e<\/i> consomem mais recursos, o que \u00e9 um grande problema se voc\u00ea faz push e pull de c\u00f3digo com frequ\u00eancia. Como os recursos podem ser distribu\u00eddos por v\u00e1rias bases de c\u00f3digo, os polyrepos podem tornar a localiza\u00e7\u00e3o de bugs mais dif\u00edcil do que encontrar a proverbial agulha no palheiro.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Com nossa estrutura polyrepo anterior \u00e0 reconstru\u00e7\u00e3o, sab\u00edamos que o futuro seria uma realidade de vasculhar reposit\u00f3rios com uma lanterna procurando pelo que precis\u00e1vamos, e que seria desafiador colaborar, dimensionar e compartilhar o c\u00f3digo \u00e0 medida que cresc\u00edamos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Estas eram nossas principais preocupa\u00e7\u00f5es:<\/b><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Desenvolvimento conjunto desafiador<\/li>\n\n\n\n<li>Forte acoplamento<\/li>\n\n\n\n<li>Escalabilidade, disponibilidade e gerenciamento de desempenho<\/li>\n\n\n\n<li>Dificuldade de compartilhar c\u00f3digo<\/li>\n\n\n\n<li>Duplica\u00e7\u00e3o<\/li>\n\n\n\n<li>Ferramentas inconsistentes<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Quando se trata de gerenciamento de c\u00f3digo-fonte, h\u00e1 muitas solu\u00e7\u00f5es, mas decidimos que uma estrutura modular de monorepo aliviaria a maioria de nossas dores de desenvolvimento no futuro.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Planos para um novo reposit\u00f3rio brilhante: uma abordagem modular<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Uma abordagem de monorepo envolve o armazenamento de todo o c\u00f3digo do projeto em um \u00fanico e grande reposit\u00f3rio<\/b>. Isso resolveria os problemas de compartilhamento e duplica\u00e7\u00e3o de c\u00f3digo que tivemos com nossa organiza\u00e7\u00e3o polyrepo, mas os monorepos n\u00e3o s\u00e3o uma solu\u00e7\u00e3o m\u00e1gica. Se o c\u00f3digo for fortemente acoplado, os monorepos tamb\u00e9m precisar\u00e3o ser projetados com modularidade.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><b>Uma abordagem modular envolve dividir um grande projeto em m\u00f3dulos menores e independentes que podem ser desenvolvidos, testados e mantidos separadamente<\/b>. Isso permite maior flexibilidade e capacidade de reutiliza\u00e7\u00e3o, bem como a capacidade de atualizar facilmente m\u00f3dulos individuais sem afetar o resto do projeto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sab\u00edamos que uma solu\u00e7\u00e3o modular e em monorepo nos permitiria ser mais eficientes com:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gera\u00e7\u00e3o de c\u00f3digo<\/li>\n\n\n\n<li>Compartilhamento de c\u00f3digo<\/li>\n\n\n\n<li>Execu\u00e7\u00e3o e orquestra\u00e7\u00e3o de tarefas distribu\u00eddas<\/li>\n\n\n\n<li>Armazenamento em 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>O TypeScript \u00e9 um superconjunto de JavaScript tipado que facilita aos desenvolvedores a constru\u00e7\u00e3o de projetos em escala.<\/b> Ele melhora a experi\u00eancia do desenvolvedor ao fornecer interfaces, aliases de tipo, an\u00e1lise est\u00e1tica de c\u00f3digo em tempo de desenvolvimento e outras ferramentas, permitindo que os desenvolvedores adicionem tipos aos seus projetos. Para nossa equipe, o TypeScript \u00e9 um conjunto de habilidades que sab\u00edamos que quer\u00edamos come\u00e7ar a buscar quando se tratava de adicionar membros \u00e0 nossa equipe.<\/div>\r\n    <\/div>\r\n\n\n\n<h2 class=\"wp-block-heading\">Pisando em calos: a dan\u00e7a da implanta\u00e7\u00e3o<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sem d\u00favida, o maior desafio de viver em um monorepo (monol\u00edtico ou n\u00e3o) \u00e9 que, quanto mais pessoas contribu\u00edrem, maior ser\u00e1 o potencial de pisarmos nos calos uns dos outros. De que adianta uma experi\u00eancia de desenvolvimento reformulada se o seu c\u00f3digo for substitu\u00eddo em uma mesclagem ruim? Se realmente estamos fazendo uma reformula\u00e7\u00e3o hol\u00edstica de nossa pilha, tamb\u00e9m devemos analisar como podemos melhorar nosso processo de implanta\u00e7\u00e3o. Esses foram os desafios mais urgentes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><b>Escalabilidade: <\/b>Seria uma m\u00e1 ideia reconstruir TODO o c\u00f3digo no monorepo para as menores altera\u00e7\u00f5es, digamos, corrigir um erro de digita\u00e7\u00e3o em algum texto. Era exatamente isso que est\u00e1vamos fazendo em nosso sistema antigo. O novo processo aproveitaria os recursos integrados do NX para avaliar e reconstruir apenas os arquivos afetados pela altera\u00e7\u00e3o, no n\u00edvel mais granular.<\/li>\n\n\n\n<li><b>Implanta\u00e7\u00e3o: <\/b>Mantivemos a maior parte da estrutura do nosso pipeline de implanta\u00e7\u00e3o. Uma vez que a imagem \u00e9 constru\u00edda, ela vai para o GitHub Container Repository. Nossa equipe de SRE ajustou nosso sistema de implanta\u00e7\u00e3o durante a migra\u00e7\u00e3o da AWS para o GCP. Podemos implantar facilmente qualquer ramifica\u00e7\u00e3o do nosso canal de implanta\u00e7\u00e3o no Slack, com um relat\u00f3rio mais agrad\u00e1vel gra\u00e7as a uma adi\u00e7\u00e3o recente que obtivemos durante a migra\u00e7\u00e3o.<\/li>\n\n\n\n<li><b>CI\/CD:<\/b> Nosso sistema antigo usava uma vers\u00e3o realmente antiga do Jenkins para executar testes e construir\/distribuir nossas imagens de aplicativo por tr\u00e1s de uma VPN. Quando a compila\u00e7\u00e3o falhava, precis\u00e1vamos de um desenvolvedor s\u00eanior de alto n\u00edvel, familiarizado com as antigas formas, para consert\u00e1-la. Em nosso novo sistema, t\u00ednhamos o plano de migrar para o GitHub Actions, onde as configura\u00e7\u00f5es s\u00e3o acess\u00edveis, declarativas e bem documentadas.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Desafios falsos e solu\u00e7\u00f5es excelentes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Projetos de qualquer tipo apresentam desafios, tanto os esperados quanto os surpreendentes. Sab\u00edamos que precis\u00e1vamos ter um plano para superar alguns problemas e que a nova vers\u00e3o do aplicativo precisava focar no desempenho sob v\u00e1rios \u00e2ngulos.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Pro\u00adble\u00admas iden\u00adti\u00adfi\u00adca\u00addos<\/th><th>So\u00adlu\u00ad\u00e7\u00f5es pro\u00adpos\u00adtas<\/th><\/tr><\/thead><tbody><tr><td><strong>Con\u00adven\u00ad\u00e7\u00f5es de c\u00f3\u00addi\u00adgo pou\u00adco cla\u00adras<\/strong><br>As con\u00adven\u00ad\u00e7\u00f5es de c\u00f3\u00addi\u00adgo re\u00adfe\u00adrem-se ao con\u00adjun\u00adto de es\u00adti\u00adlos de pro\u00adgra\u00adma\u00ad\u00e7\u00e3o, so\u00adlu\u00ad\u00e7\u00f5es e pa\u00addr\u00f5es reu\u00adti\u00adli\u00adz\u00e1\u00adveis den\u00adtro de uma ba\u00adse de c\u00f3\u00addi\u00adgo. Ima\u00adgi\u00adne uma equi\u00adpe de car\u00adpin\u00adtei\u00adros tra\u00adba\u00adlhan\u00addo em um pro\u00adje\u00adto. Se el\u00ades man\u00adti\u00adve\u00adrem 1.00\u00ad0 fer\u00adra\u00admen\u00adtas es\u00adpe\u00adci\u00ada\u00adli\u00adza\u00addas no lo\u00adcal de tra\u00adba\u00adlho, \u00e9 pro\u00adv\u00e1\u00advel que um tra\u00adba\u00adlha\u00addor es\u00adco\u00adlha a fer\u00adra\u00admen\u00adta er\u00adra\u00adda pa\u00adra o tra\u00adba\u00adlho ou a uti\u00adli\u00adce de ma\u00adnei\u00adra in\u00ada\u00adde\u00adqua\u00adda. E, ao con\u00adtr\u00e1\u00adrio das fer\u00adra\u00admen\u00adtas f\u00ed\u00adsi\u00adcas, as de\u00adpen\u00add\u00ean\u00adcias de soft\u00adwa\u00adre po\u00addem se tor\u00adnar de\u00adsa\u00adtu\u00ada\u00adli\u00adza\u00addas, ini\u00adbin\u00addo fu\u00adtu\u00adras atu\u00ada\u00adli\u00adza\u00ad\u00e7\u00f5es na ba\u00adse de c\u00f3\u00addi\u00adgo.<\/td><td><strong>Gu\u00adia de es\u00adti\u00adlo de c\u00f3\u00addi\u00adgo<\/strong><br>Man\u00adter gu\u00adias ex\u00adpl\u00ed\u00adci\u00adtos de es\u00adti\u00adlo de pro\u00adgra\u00adma\u00ad\u00e7\u00e3o\u00a0e um con\u00adjun\u00adto m\u00ed\u00adni\u00admo de pa\u00addr\u00f5es sim\u00adples e po\u00adde\u00adro\u00adsos aju\u00adda a re\u00addu\u00adzir a re\u00addun\u00add\u00e2n\u00adcia, in\u00adcon\u00adsis\u00adt\u00ean\u00adcias e com\u00adple\u00adxi\u00adda\u00adde, e po\u00adde a\u00adt\u00e9 re\u00adsul\u00adtar em de\u00adsem\u00adpe\u00adnho me\u00adlho\u00adra\u00addo. Reutilizar um pequeno conjunto de solu\u00e7\u00f5es e padr\u00f5es generalizados torna o c\u00f3digo mais f\u00e1cil de entender e reduz a probabilidade de bugs dif\u00edceis de encontrar.<\/td><\/tr><tr><td>Reu\u00adti\u00adli\u00adzar um pe\u00adque\u00adno con\u00adjun\u00adto de so\u00adlu\u00ad\u00e7\u00f5es e pa\u00addr\u00f5es ge\u00adne\u00adra\u00adli\u00adza\u00addos tor\u00adna o c\u00f3\u00addi\u00adgo mais f\u00e1\u00adcil de en\u00adten\u00adder e re\u00addu\u00adz a pro\u00adba\u00adbi\u00adli\u00adda\u00adde de bugs\u00ad di\u00adf\u00ed\u00adceis de en\u00adcon\u00adtrar. No en\u00adtan\u00adto, 90% do nos\u00adso ar\u00adma\u00adze\u00adna\u00admen\u00adto Re\u00addux\u00ad era a\u00adpe\u00adnas um ca\u00adche de re\u00adde glo\u00adri\u00adfi\u00adca\u00addo. O Re\u00addux\u00ad e\u00adxi\u00adge m\u00fal\u00adti\u00adplas ca\u00adma\u00addas de so\u00adbre\u00adcar\u00adga pa\u00adra ca\u00adda mem\u00adbro do es\u00adta\u00addo. Is\u00adso re\u00adsul\u00adtou em mui\u00adtas re\u00addun\u00add\u00e2n\u00adcias e com\u00adple\u00adxi\u00adda\u00adde des\u00adne\u00adces\u00ads\u00e1\u00adria.<\/td><td><strong>Se\u00adpa\u00adrar o ca\u00adche da re\u00adde e o es\u00adta\u00addo do a\u00adpli\u00adca\u00adti\u00advo<\/strong><br>A se\u00adpa\u00adra\u00ad\u00e7\u00e3o dos re\u00adcur\u00adsos de ca\u00adche de re\u00adde do es\u00adta\u00addo do a\u00adpli\u00adca\u00adti\u00advo nos per\u00admi\u00adte man\u00adter um ras\u00adtro de es\u00adta\u00addo mui\u00adto me\u00adnor. O es\u00adta\u00addo po\u00adde ser im\u00adple\u00admen\u00adta\u00addo mais\u00ad lo\u00adcal\u00admen\u00adte. A so\u00adbre\u00adcar\u00adga re\u00addu\u00adzi\u00adda re\u00adsul\u00adta em mai\u00ador de\u00adsem\u00adpe\u00adnho e d\u00ad\u00e1 aos de\u00adsen\u00advol\u00adve\u00addo\u00adres mai\u00ads con\u00adtro\u00adle so\u00adbre co\u00admo os da\u00addos s\u00e3o usa\u00addos.<br>N\u00f3s es\u00adco\u00adlhe\u00admos o Re\u00adact\u00ad Que\u00adry\u00a0co\u00admo a in\u00adter\u00adfa\u00adce pa\u00adra nos\u00adsas APIs de back-end\u00ad, per\u00admi\u00adtin\u00addo ge\u00adren\u00adci\u00adar\u00admos os da\u00addos de for\u00adma as\u00ads\u00edn\u00adcro\u00adna com fa\u00adci\u00adli\u00adda\u00adde e re\u00addu\u00adzir a so\u00adbre\u00adcar\u00adga de re\u00adde.<\/td><\/tr><tr><td><strong>Ar\u00adqui\u00adte\u00adtu\u00adra de re\u00adde em ca\u00adma\u00addas m\u00fal\u00adti\u00adplas<\/strong><br>Nos\u00adso a\u00adpli\u00adca\u00adti\u00advo cres\u00adceu or\u00adga\u00adni\u00adca\u00admen\u00adte de um pai\u00adnel de con\u00adtro\u00adle b\u00e1\u00adsi\u00adco cen\u00adtra\u00addo na API\u00ad pa\u00adra o pa\u00adco\u00adte mul\u00adti\u00adpro\u00addu\u00adto de fer\u00adra\u00admen\u00adtas pa\u00adra clien\u00adtes que te\u00admos ho\u00adje. In\u00adi\u00adci\u00adal\u00admen\u00adte, o clien\u00adte foi cons\u00adtru\u00ad\u00ed\u00addo so\u00adbre fer\u00adra\u00admen\u00adtas co\u00admuns de Py\u00adthon com\u00adpar\u00adti\u00adlha\u00addas por mui\u00adtos dos nos\u00adsos back-ends de API. Isso leva a termos in\u00fameras camadas de middleware necess\u00e1rias mesmo para a chamada de API mais simples. Is\u00adso n\u00e3o a\u00adpe\u00adnas di\u00adfi\u00adcul\u00adtou o en\u00adten\u00addi\u00admen\u00adto da o\u00adri\u00adgem de qual\u00adquer da\u00addo, co\u00admo tam\u00adb\u00e9m tor\u00adnou a i\u00adden\u00adti\u00adfi\u00adca\u00ad\u00e7\u00e3o de bugs\u00ad na pi\u00adlha de re\u00adde mui\u00adto de\u00admo\u00adra\u00adda.<\/td><td><strong>API p\u00fa\u00adbli\u00adca pri\u00admei\u00adro<\/strong><br>Em ve\u00adz de pas\u00adsar as so\u00adli\u00adci\u00adta\u00ad\u00e7\u00f5es por v\u00e1\u00adrios pro\u00adxies, ca\u00adma\u00addas de au\u00adten\u00adti\u00adca\u00ad\u00e7\u00e3o e in\u00adter\u00adfa\u00adces em Py\u00adthon, de\u00adci\u00addi\u00admos lo\u00adgo no in\u00ad\u00ed\u00adcio que\u00ad sem\u00adpre que pos\u00ads\u00ed\u00advel, co\u00adle\u00adta\u00adr\u00ed\u00ada\u00admos os da\u00addos ne\u00adces\u00ads\u00e1\u00adrios di\u00adre\u00adta\u00admen\u00adte do clien\u00adte u\u00adsan\u00addo as APIs\u00ad dis\u00adpo\u00adn\u00ed\u00adveis pu\u00adbli\u00adca\u00admen\u00adte. Is\u00adso n\u00e3o a\u00adpe\u00adnas re\u00addu\u00adziu sig\u00adni\u00adfi\u00adca\u00adti\u00adva\u00admen\u00adte nos\u00adsa so\u00adbre\u00adcar\u00adga e com\u00adple\u00adxi\u00adda\u00adde, co\u00admo\u00ad nos a\u00adju\u00addou a per\u00adce\u00adber me\u00adlhor nos\u00adsos ser\u00advi\u00ad\u00e7os de API\u00ad a par\u00adtir das pers\u00adpec\u00adti\u00advas de nos\u00adsos clien\u00adtes. N\u00f3s pre\u00adten\u00adde\u00admos le\u00advar es\u00adsa i\u00adni\u00adci\u00ada\u00adti\u00adva a\u00addi\u00adan\u00adte no fu\u00adtu\u00adro pr\u00f3\u00adxi\u00admo, tor\u00adnan\u00addo mai\u00ads das nos\u00adsas APIs p\u00fa\u00adbli\u00adcas.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">N\u00e3o jogue o beb\u00ea fora junto com a \u00e1gua do banho<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Escrevemos centenas de milhares de linhas de c\u00f3digo na \u00faltima d\u00e9cada. Escrevemos centenas de milhares de linhas de c\u00f3digo na \u00faltima d\u00e9cada. Isso seria invi\u00e1vel. Precis\u00e1vamos encontrar uma maneira de continuar incorporando esses recursos existentes sem comprometer nossos objetivos para a nova pilha. Encontramos uma solu\u00e7\u00e3o em uma tecnologia chamada module federation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Com o plugin de module federation do Webpack, pudemos <b>criar uma nova compila\u00e7\u00e3o do nosso aplicativo antigo com mudan\u00e7as m\u00ednimas<\/b>, o que seria capaz de integrar os recursos existentes na nova pilha do portal. Ainda ter\u00edamos um objetivo de longo prazo de portar o c\u00f3digo agora legado para padr\u00f5es mais recentes, mas isso nos permitiria come\u00e7ar a escrever novos recursos com os novos benef\u00edcios imediatamente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ainda ter\u00edamos um objetivo de longo prazo de portar o c\u00f3digo legado para padr\u00f5es mais recentes, mas isso nos permitiria come\u00e7ar a escrever novos recursos com os novos benef\u00edcios imediatamente.<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sab\u00edamos que consolidar nossas plataformas enquanto ampli\u00e1vamos continuamente os recursos e conjuntos de produtos exigiria um esfor\u00e7o maci\u00e7o, e nosso planejamento influenciou o que quer\u00edamos para nossa nova pilha de front-end, e como gerenciar\u00edamos o legado imortal de sistemas de estilo CSS antiquados, padr\u00f5es de componentes de classe descontinuados e gerenciamento desajeitado do estado do aplicativo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como est\u00e1vamos construindo do zero \u2013 especialmente com a migra\u00e7\u00e3o da AWS para o Google Cloud \u2013 <b>a melhor solu\u00e7\u00e3o foi uma ruptura total<\/b>. Um novo reposit\u00f3rio com padr\u00f5es melhores e mais elevados, module federation, bibliotecas modulares e compartilhadas, e uma documenta\u00e7\u00e3o interna e voltada para o usu\u00e1rio mais abrangente.<\/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\">Foi\u00a0uma etapa intensa de planejamento e prepara\u00e7\u00e3o. Foi\u00a0uma etapa intensa de planejamento e prepara\u00e7\u00e3o.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fase 2? Transformar a ideia em realidade \u2013 e isso envolveu muito mais equipes. Desenvolvedores, acredito que nossa aventura est\u00e1 prestes a tomar um rumo muito interessante. <\/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_6f53aed124403b0d08206253bc3d4f8f\">\r\n                            <p class=\"h4 text-accent fw-bold\" id=\"banner-block-block_6f53aed124403b0d08206253bc3d4f8f\">\r\n                Confira a Parte 2 \u2013 Uma execu\u00e7\u00e3o muito triunfante            <\/p>\r\n                            <div class=\"mb-0 text-body-color\">\r\n                                    <div class=\"content-body mb-0 text-body-color\">Na parte 1, respondemos \u00e0 pergunta: Por que reconstruir? Na parte 2, vamos mergulhar na implementa\u00e7\u00e3o e execu\u00e7\u00e3o. Tem drama, tem migra\u00e7\u00f5es&#8230; e provavelmente muitas refer\u00eancias \u00e0 fic\u00e7\u00e3o cient\u00edfica. Junte-se a n\u00f3s nesta jornada.<\/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>Sauda\u00e7\u00f5es, colegas desenvolvedores. Estamos empolgados em anunciar que, ap\u00f3s tr\u00eas longos anos de planejamento, design e constru\u00e7\u00e3o, nossa equipe lan\u00e7ou nossa fant\u00e1stica atualiza\u00e7\u00e3o de aplicativo. Claro, temos trabalhado incansavelmente para atualizar a apar\u00eancia de nossa interface de usu\u00e1rio, mas fizemos uma reformula\u00e7\u00e3o ainda mais ousada em nossa pilha de tecnologia fundamental. O que isso significa [&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-15013","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>Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun<\/title>\n<meta name=\"description\" content=\"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.\" \/>\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\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"og:description\" content=\"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/\" \/>\n<meta property=\"og:site_name\" content=\"Transactional Email API Service For Developers | Mailgun\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-24T04:59:17+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 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/\",\"name\":\"Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/#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-24T04:59:17+00:00\",\"description\":\"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/#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\\\/pt\\\/blog\\\/dev-life\\\/mailgun-app-rebuild-part-one\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/inicio\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Um mergulho profundo na reconstru\u00e7\u00e3o do aplicativo Mailgun: Parte 1 \u2013 Ideias excelentes\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#website\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"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\\\/pt\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#organization\",\"name\":\"Transactional Email API Service For Developers | Mailgun\",\"url\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.mailgun.com\\\/pt\\\/#\\\/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\\\/pt\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun","description":"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.","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\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/","og_locale":"pt_BR","og_type":"article","og_title":"Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun","og_description":"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.","og_url":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/","og_site_name":"Transactional Email API Service For Developers | Mailgun","article_modified_time":"2026-07-24T04:59:17+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 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/","url":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/","name":"Como reconstru\u00edmos nosso aplicativo Mailgun para v\u00e1rios produtos: Parte 1 - Transactional Email API Service For Developers | Mailgun","isPartOf":{"@id":"https:\/\/www.mailgun.com\/pt\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/#primaryimage"},"image":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/#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-24T04:59:17+00:00","description":"A atualiza\u00e7\u00e3o rec\u00e9m-lan\u00e7ada do aplicativo Mailgun come\u00e7ou como uma opera\u00e7\u00e3o de base. Quer ver como fizemos isso acontecer? Junte-se a n\u00f3s nesta excelente aventura.","breadcrumb":{"@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/#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\/pt\/blog\/dev-life\/mailgun-app-rebuild-part-one\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.mailgun.com\/pt\/inicio\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/www.mailgun.com\/pt\/blog\/"},{"@type":"ListItem","position":3,"name":"Um mergulho profundo na reconstru\u00e7\u00e3o do aplicativo Mailgun: Parte 1 \u2013 Ideias excelentes"}]},{"@type":"WebSite","@id":"https:\/\/www.mailgun.com\/pt\/#website","url":"https:\/\/www.mailgun.com\/pt\/","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\/pt\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.mailgun.com\/pt\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.mailgun.com\/pt\/#organization","name":"Transactional Email API Service For Developers | Mailgun","url":"https:\/\/www.mailgun.com\/pt\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.mailgun.com\/pt\/#\/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\/pt\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/15013","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/users\/17"}],"version-history":[{"count":4,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/15013\/revisions"}],"predecessor-version":[{"id":15119,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog\/15013\/revisions\/15119"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media\/3952"}],"wp:attachment":[{"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/media?parent=15013"}],"wp:term":[{"taxonomy":"blog_category","embeddable":true,"href":"https:\/\/www.mailgun.com\/pt\/wp-json\/wp\/v2\/blog_category?post=15013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}