Conheça os Principais Recursos do NestJS

Se você, assim como eu, valoriza a organização e a estrutura no desenvolvimento, provavelmente prefere linguagens como TypeScript e frameworks que impõem um padrão de trabalho, como Angular. Essa preferência não torna uma opção melhor que a outra, mas sim reflete diferentes abordagens. Particularmente, me inclino por ferramentas que oferecem uma base sólida para o desenvolvimento backend.

## Por que escolher NestJS para Backend com TypeScript?

Nesse contexto, NestJS com TypeScript se destaca por proporcionar uma estrutura clara e organizada para o desenvolvimento backend. Embora possa apresentar desafios, sua base em princípios como injeção de dependências e arquitetura modular resulta em um código mais fácil de manter e escalar.

A seguir, apresento um resumo da arquitetura básica que o NestJS utiliza.

## Módulos em NestJS

A ideia central do NestJS é dividir o projeto em módulos. Mas o que é exatamente um módulo? Podemos entendê-lo como uma unidade fundamental que encapsula uma parte da lógica de negócio.

Por exemplo, imagine que o cliente precisa de um blog com posts e usuários. Numa análise inicial, podemos identificar dois módulos principais:

* Módulo de Usuários
* Módulo de Posts

Cada módulo, por sua vez, é organizado em componentes essenciais:

* Controlador: Lida com as requisições HTTP e define os endpoints do módulo.
* Serviço: Contém a lógica de negócio e atua como intermediário entre o controlador e os dados.
* Dados: Representados por entidades, repositórios ou modelos que interagem com o database.

Para definir um módulo, a estrutura é a seguinte:

### Controladores

O controlador de um módulo é uma classe cuja única função é expor os endpoints do módulo e interagir com o cliente. Ele recebe as requisições e retorna as respostas, mas não implementa nenhuma lógica de negócio.

É importante lembrar que o controlador deve implementar o serviço, mas no exemplo anterior, ele não foi usado para facilitar a compreensão.

### Serviços

Os serviços são classes encarregadas de executar a lógica de negócio. Eles recebem os dados do controlador, processam e realizam as operações necessárias antes de retornar uma resposta.

Os serviços são o coração da aplicação e permitem manter uma arquitetura limpa e bem organizada.

Vale ressaltar que o serviço implementa a classe responsável por acessar os dados. No entanto, no exemplo anterior, isso não foi feito para simplificar o entendimento. O serviço nunca acessa os dados diretamente.

### Dados (Repositórios)

Os dados ou repositórios são classes dedicadas exclusivamente ao acesso e gestão de dados. Eles obtêm informações de bancos de dados, arquivos, outras APIs ou qualquer outra fonte externa.

A função dos repositórios é separar a lógica de acesso a dados do restante da aplicação, facilitando a manutenção e escalabilidade do projeto.

Neste caso, não será fornecido um exemplo, pois a implementação da classe varia dependendo da biblioteca utilizada (mongoose, typeorm, prisma) e do banco de dados empregado.

### Resumo

Em um módulo de NestJS, temos três classes bem distintas, cada uma com uma responsabilidade específica:

* Controlador: Recebe as requisições e retorna as respostas.
* Serviço: Executa a lógica de negócio.
* Repositório: Acessa e gerencia os dados.

Cada classe cumpre sua função sem interferir na responsabilidade das demais, mantendo uma separação clara de responsabilidades.

Além disso, elas seguem uma hierarquia em que cada camada só interage com a inferior:

* O controlador utiliza o serviço, mas o serviço não tem conhecimento do controlador.
* O serviço utiliza os repositórios ou fontes de dados, mas estes não conhecem o serviço.

Essa estrutura segue os princípios de Domain-Driven Design (DDD) e Clean Architecture. Isso é uma grande vantagem, pois permite manter uma separação clara de responsabilidades, o que facilita a organização do código e melhora a testabilidade de cada componente de forma independente.

## Injeção de Dependências

Outra característica fundamental do NestJS é seu sistema de injeção de dependências, um conceito utilizado em frameworks como Spring Boot. Esse mecanismo é fundamental para alcançar maior flexibilidade e modularidade nas aplicações.

Ao aplicar esse padrão, evitamos a necessidade de instanciar manualmente as classes. Ou seja, nunca criaremos objetos com new UserService(). Em vez disso, indicamos que precisamos de uma classe do tipo UserService, e o NestJS se encarrega de gerenciar sua instância.

Por padrão, as classes que injetamos são do tipo Singleton (DEFAULT). É importante considerar isso em certas situações.

Quando uma classe é solicitada, o Nest verifica em seu registro interno se já existe uma instância disponível. Se sim, ele a reutiliza; caso contrário, ele a cria automaticamente. Por padrão, todas as classes injetadas são Singleton, o que significa que são instanciadas uma única vez e compartilhadas em toda a aplicação, otimizando o uso de recursos.

Essa abordagem não só torna o código mais limpo e fácil de manter, mas também facilita a escalabilidade do projeto.

### Injectable

Qualquer classe anotada com @Injectable é gerenciada pelo contêiner de dependências (IoC) do NestJS. Se, por exemplo, tivermos uma classe de utilidades que queremos usar no módulo de Usuário, devemos importar essa classe no módulo e declará-la dentro do array de providers. Feito isso, já podemos aproveitar a injeção de dependências.

Existem duas formas principais de injetar dependências:

* No construtor: a forma recomendada e padrão.
* Nas propriedades: utilizada em casos específicos, como quando trabalhamos com herança e precisamos chamar o método super() da classe pai.

### Injeção no construtor

Esta é a forma mais comum e simples de fazer isso. Quando encontramos uma classe com um construtor que tem um ou mais argumentos, estes geralmente serão outras classes (ou valores) que o NestJS injeta automaticamente nessa classe.

No exemplo anterior, temos o controlador UserController e o serviço UserService. De acordo com a arquitetura proposta, o controlador deve utilizar o serviço. Para conseguir isso, injetamos o serviço no construtor do controlador, e o NestJS se encarrega automaticamente do resto.

### Injeção em propriedades

Embora menos comum, essa técnica também é válida. Usamos em situações específicas, como quando uma classe herda de outra e precisamos chamar o método super() do pai. Isso evita que tenhamos que modificar ambas as classes. Para fazer isso, usamos o decorador @Inject() e passamos o token ou a classe que queremos injetar na propriedade.

Essa opção também é válida para a injeção.

Primeira: Este conteúdo foi auxiliado por Inteligência Artificiado, mas escrito e revisado por um humano.

Segunda: Uma frase em itálico “Via e então insira o nome do site que foi usado como referência como âncora do link de referência https://dev.to/dragosb/lo-mejor-de-nestjs-5160 com tag nofollow. Por exemplo: Via Nome do site do RSS

Leave a Comment

Exit mobile version