Alura > Cursos de Programação > Cursos de Node.JS > Conteúdos de Node.JS > Primeiras aulas do curso Node.js: migração de monolito para microsserviços

Node.js: migração de monolito para microsserviços

Planejando a migração da aplicação - Apresentação

Apresentando os instrutores

Olá! Vamos começar uma jornada incrível no mundo dos microserviços, entendendo como criar aplicações concisas, performáticas e escaláveis. Nesta primeira aula, vamos nos apresentar.

Meu nome é Anderson Mello, sou engenheiro de software sênior, trabalho com JavaScript e TypeScript de alta performance. Também atuo como tech lead e arquiteto de soluções corporativas, especialmente no universo do TypeScript.

Audiodescrição: Anderson é um homem branco, com cabelo e barba loiros. Seu cabelo é curto e está ficando calvo. Ele tem olhos azuis, que estão escondidos atrás de óculos redondos.

Introduzindo o curso de microserviços

Agora que já nos conhecemos um pouco, vamos entender o que aprenderemos neste curso de microserviços. Primeiramente, vamos compreender as diferenças entre monólitos e microserviços, tanto na teoria quanto na prática. Em seguida, abordaremos planos e estratégias de migração, explorando como transitar de um para o outro.

Mais importante do que saber como chegar, precisamos entender nossos motivos. Vamos discutir onde aplicar monólitos e, principalmente, onde aplicar microserviços.

Explorando estratégias e ferramentas

Precisamos compreender isso para saber como vamos proceder e por que vamos fazê-lo. Além disso, vamos entender as estratégias de comunicação entre os serviços, seguindo diversos protocolos, e também sobre a consistência de dados, que é um tema extremamente sensível e essencial para o sucesso e a performance de nosso microserviço.

Como fizemos em outros cursos, também vamos utilizar o que há de mais novo no mercado. Vamos aprender a utilizar o NestJS para construir não apenas uma aplicação monolítica, mas também para entender como construir uma arquitetura robusta, limpa e eficaz.

Compreendendo os pilares da arquitetura

Mais importante do que tudo isso, vamos entender os três pilares de cada arquitetura. Não adianta aplicarmos uma solução exagerada para um problema simples. Vamos entender como cada decisão afeta a construção de nosso microserviço.

Quando tivermos tudo isso e nosso plano de migração estiver consolidado, vamos refatorar o módulo preparado em nosso projeto para uma arquitetura de microserviços, permitindo que compreendamos como tudo isso funciona na prática.

Concluindo a introdução e próximos passos

Temos muito conteúdo de qualidade e muitas novidades acontecendo. Aguardamos vocês no próximo vídeo para começarmos a aplicar tudo e entender como esse universo pode nos ajudar a desenvolver software de qualidade. Até a nossa próxima e primeira aula.

Planejando a migração da aplicação - Explorando o projeto Edufy Monolito

Introduzindo o curso de microserviços

É um prazer tê-los de volta, todos que estão acompanhando o início do nosso curso de microserviços. Agora que já nos conhecemos, a ideia é começarmos a entender, a partir de um ponto inicial, o que é uma aplicação monolítica. Provavelmente já temos uma base sobre isso, mesmo que não tenhamos uma definição formal. Vamos partir dessa definição de monolito para entender suas limitações e o motivo pelo qual os microserviços existem. Quais problemas eles estão aqui para resolver? Após isso, começaremos a nos aprofundar no tema de microserviços, que é um universo extenso.

Vamos iniciar a partir de um projeto que já foi trabalhado em outro curso da Alura, o curso de monolitos modulares. Utilizaremos esse projeto como ponto de partida, pois é o gancho perfeito para sairmos de um projeto pensado para ser um monolito, construído da maneira mais eficiente possível, aplicando boas práticas na escrita de código. Vamos transitar de uma arquitetura bem estruturada, com suas limitações, para uma arquitetura de microserviços.

Explorando o projeto Edufy Monolito

Antes de seguirmos para os nossos slides e começarmos a traçar o paralelo entre microserviços e monolitos, vale a pena darmos uma olhada no nosso projeto. Temos aqui o projeto Edufy, que possui funcionalidades de uma escola digital. Este será o projeto que utilizaremos como ponto de partida, nomeado como Edufy Monolito, e a partir dele faremos nossas migrações para uma arquitetura de microserviços.

Dando uma visão geral da nossa aplicação, trata-se de uma aplicação em NestLTS. Dentro da pasta src, temos o nosso aplicativo propriamente dito, uma pasta de libs com algumas ferramentas que utilizaremos para fazer a aplicação funcionar, e o nosso ponto de entrada da aplicação. É algo muito simples e direto. Existem algumas outras configurações, mas vamos nos aprofundar nelas conforme avançarmos. Caso desejem, podem retornar ao curso de monolitos para entender o que cada uma dessas configurações faz. O link para o curso estará disponível, e se houver dúvidas sobre o processo de construção desse monolito, podem revisitar o curso ou refazê-lo do zero, pois será um conteúdo enriquecedor.

Delimitando escopos e módulos da aplicação

Dentro da nossa aplicação, temos alguns escopos que precisamos delimitar. Temos a parte administrativa, destinada ao back office da aplicação, o domínio de curso, um módulo de debug, e também os módulos de ticket e de domínio de usuários. Além disso, lidamos com autenticação e toda a infraestrutura de usuário, incluindo informações. Na pasta Libs, há outras funcionalidades que conheceremos ao longo do curso.

Ao observarmos os módulos, percebemos que eles seguem os padrões do DDD (Domain-Driven Design). Temos Application, Domain, Infrastructure e Presentation. Para contextualizar, o Presentation é a interface com o usuário, a parte com a qual o usuário interage. O domínio é a parte mais interna da aplicação, idealmente agnóstica a frameworks e bibliotecas, sendo o mais puro possível. A infraestrutura conecta a apresentação ao domínio e entre as camadas da aplicação. O Application é a parte de serviços da aplicação, onde estão as regras de negócio dentro daquele domínio.

Visualizando a arquitetura monolítica

Preparei um diagrama para termos uma noção de como está nossa arquitetura atual, o Monolith Edify. Vou ampliar para facilitar a visualização. Como em toda aplicação, começamos com o usuário, que interage a partir da interface. Em uma aplicação monolítica, temos a interface de usuário. Podemos ter um monorepo com back-end e front-end. No momento, focamos apenas no back-end, mas é possível que a arquitetura não esteja desacoplada do front-end.

Seguindo o fluxo de interação dos usuários, passamos para a lógica de negócio, ou seja, os módulos da aplicação. Na estrutura monolítica, temos um ponto de entrada único, que também existirá na aplicação de microserviços. A diferença é que esse ponto de entrada único já pertence à aplicação e está dentro da arquitetura monolítica. Temos alguns módulos no curso: um módulo de autenticação, necessário para proteger rotas e restringir o acesso de usuários; um módulo de gerenciamento de cursos, voltado para o escopo administrativo; um módulo de matrículas, responsável pelas matrículas dos usuários; um módulo de pagamentos; e um módulo de usuários.

Comparando monolitos e microserviços

Uma das principais diferenças entre a arquitetura monolítica e a de microserviços é que todos esses módulos se conectam a uma única camada de acesso a dados, que por sua vez se conecta a um único banco de dados. Quando migramos para uma arquitetura de microserviços, as coisas começam a mudar. Preparei outro diagrama para ilustrar essa transição.

Vamos analisar como funciona uma infraestrutura voltada principalmente para o back-end. O fluxo começará essencialmente da mesma forma: quem geralmente dispara nossa requisição é um cliente. Claro que poderíamos ter outra API consumindo os dados da nossa aplicação, mas neste cenário será um cliente web. Durante o curso, utilizaremos o Postman ou outras formas para disparar essas requisições.

Explorando a arquitetura de microserviços

Pegamos como exemplo um endpoint para matrículas. Vamos falar do escopo de matrículas, mas poderíamos fazer esse diagrama para qualquer escopo. Aqui entra a primeira diferença da nossa arquitetura de microserviços: o Gateway será uma aplicação completamente separada dos nossos microserviços. Ele não faz mais parte de um único serviço; assim como os outros, é também um microserviço. O Gateway é responsável por fazer o roteamento das requisições que chegam até cada um dos serviços que precisam dessa informação e que vão trabalhar com ela.

Depois que recebemos essa informação no Gateway, teremos nossos microserviços independentes. Estamos falando da parte de matrícula, mas antes de prosseguir, vamos observar que teremos serviços independentes para catálogo, por exemplo, e esse serviço de catálogo terá seu banco de dados separado. Isso é uma diferença significativa em relação a uma arquitetura monolítica. Teremos o serviço de identidade, que lidará com toda a parte de usuário e também terá seu banco de dados, e também o serviço de matrículas, que lidará com o endpoint e a lógica de negócio das matrículas. O Gateway roteia as informações para o serviço correto, e nosso serviço de matrícula processa essas informações. Nesse cenário, ele publicará um evento de que o estudante foi matriculado para o nosso broker, que será responsável pela comunicação assíncrona.

Avaliando prós e contras das arquiteturas

Podemos ter também um serviço de autenticação e autorização para lidar separadamente com isso do Gateway. No entanto, essa é geralmente uma definição muito particular de cada arquitetura, empresa e desafio de cada sistema que será implementado na vida real.

Quais são os principais prós de uma aplicação que está toda em um único local e estrutura? Primeiro, iniciar esse projeto é muito mais simples. Geralmente, precisamos nos preocupar com um único repositório, e a performance para projetos menores é um ponto tranquilo, pois não há tanta preocupação em escalar. No entanto, escalar uma aplicação monolítica é mais complicado do que escalar uma aplicação em microserviços. Em uma aplicação monolítica, temos uma escala vertical, ou seja, precisamos aumentar a quantidade de aplicações que temos, mas ao escalar verticalmente, escalamos tudo. Todos os módulos estão acoplados em um único serviço, e mudanças em um módulo podem impactar globalmente. Além disso, ficamos presos a uma tecnologia, perdendo a flexibilidade de usar diferentes linguagens e frameworks para resolver problemas específicos.

Quando migramos para uma aplicação em microserviços, também encontramos prós e contras. Entre os prós, temos a escalabilidade independente. Em um cenário como a Black Friday, por exemplo, se tivermos uma aplicação monolítica, precisaremos escalar todos os módulos. Com uma aplicação em microserviços, podemos escalar apenas as partes mais requisitadas, como cursos e matrículas. Isso nos dá autonomia e liberdade tecnológica para selecionar tecnologias específicas para resolver problemas específicos.

Contudo, essa arquitetura traz um aumento da complexidade operacional. Precisamos gerenciar múltiplos deploys, recursos e repositórios, o que tem um custo. A comunicação não ocorre mais em memória, mas pela rede, seja pelo protocolo TCP, message broker, gRPC, etc., dependendo do cenário de cada microserviço. Além disso, precisamos nos preocupar com a consistência de dados, pois teremos vários bancos em vários serviços que precisam se comunicar e garantir que os dados estejam consistentes entre eles.

Concluindo a introdução e próximos passos

Agora que tivemos esse primeiro vislumbre dos prós e contras de cada arquitetura, na próxima aula vamos conhecer a tecnologia que utilizaremos. Falaremos mais sobre o NetJS e as vantagens de utilizá-lo para construir nosso microserviço. Nos vemos na próxima aula. Até mais!

Planejando a migração da aplicação - Microserviços e comunicação com NestJS

Introduzindo o NestJS como ferramenta para microserviços

Agora que já conhecemos nossa aplicação base, os prós e contras da arquitetura de microserviços e os fatores que nos levam a escolher essa abordagem em um cenário real, partindo de um monolito, vamos nos aprofundar naquele que será nosso aliado na construção dos serviços que implementaremos no curso de microserviços. Utilizaremos o framework mais popular para construção de back-end no universo do JavaScript. Para quem tem experiência em front-end, o NestJS é conhecido como o Angular do back-end. Para quem vem do Java, ou tem alguma experiência com ele, podemos dizer que o NestJS é o Spring Boot do mundo do JavaScript.

O NestJS tem a proposta de resolver uma série de problemas e dores de cabeça que encontramos no desenvolvimento de software. Muitas vezes, o framework que utilizamos não é tão completo, ou precisamos complementar seus comportamentos com outras bibliotecas. Precisamos descobrir como as coisas funcionam em conjunto com o framework. Por exemplo, ao utilizar o Express, ele funciona mais como uma biblioteca do que como um framework propriamente dito. Precisamos, muitas vezes, adicionar uma série de comportamentos através de bibliotecas que não são suportadas nativamente, o que gera uma sobrecarga na hora de montar a arquitetura de uma aplicação. Além disso, o Express não impõe uma estrutura, não é opinativo na construção da estrutura de pastas ou de como a aplicação funciona. Quando temos um time com pessoas desenvolvedoras juniores, plenas e seniores, é fácil que uma aplicação que utiliza um framework sem padrões definidos comece a sofrer com problemas de estruturação de código, o que pode se tornar um problema para a própria aplicação. Esse é um problema que o NestJS vem resolver no universo do JavaScript e do Node.js.

Explorando a documentação e conceitos fundamentais do NestJS

Antes de falarmos sobre os motivos para utilizarmos o framework, é importante destacar a importância de sermos amigos da documentação das ferramentas que usamos. O ponto de partida para quem vai desenvolver uma aplicação em microserviços neste curso é conhecer o framework NestJS. É essencial dedicar um tempo para olhar a documentação, especialmente se não temos o hábito de trabalhar com ele ou se estamos começando nossa jornada de desenvolvimento agora. O principal ponto de partida é seguir a documentação, começando pela seção de overview, os primeiros passos, e entender o que são os Controllers e Providers, que serão essenciais quando falarmos de injeção de dependência. Os módulos são as estruturas base das aplicações em NestJS, e é assim que organizamos o código. Middlewares serão necessários para comportamentos mais complexos na aplicação, assim como os Guards, que já estão em uso no projeto Edufy e serão adicionados durante o curso de microserviços. É importante dominar esses conceitos.

Depois, passamos para a parte dos fundamentos, que também é crucial conhecer. Custom Providers, Providers assíncronos, módulos dinâmicos e escopos de injeção são pontos básicos que precisamos consolidar para ter um código eficiente utilizando o NestJS. Existem algumas técnicas importantes a conhecer, como a seção de técnicas, a parte de configuração e o módulo de configuração, fundamentais para trabalhar com segurança utilizando arquivos .env. Além disso, a parte de banco de dados é essencial, pois trabalhamos diretamente com banco de dados na aplicação, especialmente quando lidamos com várias instâncias de banco para cada microserviço.

Abordando microserviços e comunicação no NestJS

A seção mais importante para o curso é a de microserviços. Aqui, temos uma série de ferramentas além do overview, que oferece uma noção de como funcionam os microserviços no universo do NestJS. Utilizamos o Redis para caching e o RabbitMQ como message broker. Para microserviços que precisam de comunicação síncrona em cenários mais complexos, podemos usar o gRPC. Há também uma seção específica para tratar pipes, guards e interceptors no contexto de microserviços distribuídos.

Destacando as vantagens do NestJS

Por fim, por que utilizamos o NestJS? Primeiro, ele é escalável e cresce bem, abstraindo muitas coisas sem sacrificar a performance. Além disso, ajuda a organizar o código. Segundo, oferece suporte a diversos protocolos de comunicação entre microserviços. Embora no curso nos concentremos em alguns, a documentação mostra várias ferramentas para comunicação entre microserviços, o que é um grande benefício do framework. Além disso, o NestJS é open source, não precisamos pagar para utilizá-lo. Mais do que isso, ele possui uma comunidade extremamente ativa. Para quem está começando ou já está há muito tempo na jornada de desenvolvimento, é quase certo que alguém já enfrentou os mesmos problemas antes. Temos fóruns e comunidades que fazem a diferença na hora de resolver problemas.

Além disso, os blocos de construção do NestJS, com módulos, controles e serviços, e mais importante de tudo, a nossa injeção de dependência, garantem que temos todo o ferramental necessário para construirmos uma aplicação robusta, funcional e muito performática.

Concluindo e preparando para a próxima aula

Agora que já conhecemos nosso framework, vamos falar mais na próxima aula sobre como planejaremos essa parte de mudança, essa parte da migração, e como colocaremos em prática aquela arquitetura de microserviços, partindo da nossa arquitetura monolítica.

Aguardamos vocês na próxima aula. Até mais!

Sobre o curso Node.js: migração de monolito para microsserviços

O curso Node.js: migração de monolito para microsserviços possui 284 minutos de vídeos, em um total de 54 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Node.JS acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas