NestJS — Framework para NodeJS

Daísa Fernandes
tecnologia no Grupo Boticário
6 min readSep 23, 2022

Construa aplicações backend eficientes e escaláveis

NestJS
NestJS

Nos dias atuais o NodeJS está sendo uma escolha muito popular na criação de web services e o NestJS veio para auxiliar nesse quesito. O NestJS é um framework para construir aplicações backend em NodeJS, muito eficiente e escalável. Além de tudo ainda suporta TypeScript 😃 (mas pode ser desenvolvido em JavaScript puro também).

Como padrão, o nest utiliza o Express como servidor HTTP padrão, porém também pode ser configurado com o Fastify. Ele também possui algumas integrações com outras ferramentas como: TypeORM, Sequelize, Mongoose, Prisma, OpenAPI, etc.

Caso você já seja um desenvolvedor Java/Spring, Angular e até mesmo C#/.NET você irá se familiarizar muito com o NestJS — como a injeção de dependência, criação de módulos, etc).

Setup

Para criar um app com o nest é necessário ter o node instalado, caso você não tenha, pode obter o node clicando aqui.

Agora para começar, instale o nest globalmente e crie eu primeiro projeto.

$ npm i -g @nestjs/cli
$ nest new projeto-nestjs

Após criado o projeto terá a seguinte estrutura:

Estutura nestjs

O nest irá gerar os arquivos, app.controller.ts, e uma classe de teste para controller app.controller.spec.ts, app.module.ts, app.service.ts e main.ts (arquivo de entrada do aplicativo que usa a função principal NestFactory para criar uma instância do aplicativo nest).

Controllers

Os Controllers são responsáveis ​​por lidar com Requests e retornar Responses ao Client. Em seu projeto você poderá ter um ou mais controllers, dependendo de como você irá estruturar.

Http Request
Http Request

Dentro do controller você pode ter mais de uma rota, e essas rotas podem realizar diferentes ações em seu projeto.

Para criar um controller vamos precisar de uma classe e decorators (decorators associam as classes aos metadados necessários e permite que o nest crie um mapa de roteamento) .

Para definir utilizamos o decorator @Controller(), como opcional podemos passar um prefixo para a rota, e isso nos permite agrupar um conjunto de rotas relacionadas dentro de um controller.

Items Controller

E agora nos métodos podemos definir com os decorators: @Get(), @Post(), @Put(), @Delete() etc.

Aqui também já temos o ItemsService sendo injetado no construtor, e isso nos permite declarar e inicializar o serviço.

Providers

Os Providers são uma parte fundamental do nest. Muitas classes são tratadas como providers, são elas: services, repositories, factories, etc. Isso significa que os providers podem ser injetados como dependência.

Service
Service/Provider
Items Service

Aqui neste service iremos ter a nossa lógica do projeto, responsável pelo armazenamento e recuperação dos dados, e será utilizado pela nossa classe do controller.

Para definir o nosso service, vamos utilizar do decorator @Injectable(), anexando os metadados, e esse decorator é gerenciado pelo IoC do nest.

Modules

Cada app possui um Module raiz, que é o ponto de partida que o nest usa para organizar a estrutura do aplicativo. Aqui utilizamos o decorator @Module().

Além do module raiz, também temos outros modules para organizar os componentes do projeto. Assim, para a maioria dos apps, a arquitetura resultante empregará vários modules, cada um encapsulando um conjunto de recursos relacionados.

Modules
Modules
Items Module
App Module

Middlewares

O Middleware é uma função que é chamada antes do handler de rota. As funções tem acesso aos objetos de request e response. Então se quisermos ter acesso antes do controller, podemos criar uma classe com o decorator @Injectable() implementando a interface NestMiddleware.

Essa função pode executar as seguintes tarefas:

  • Executar qualquer código.
  • Fazer alterações nos objetos de request e de response.
  • Encerrar o ciclo request-response.
  • Chamar um outro middleware.
Middleware
Middleware
Logger Middleware

Para configurar o middleware, usamos o método configure() da classe do module. App que incluem middleware precisam implementar a interface NestModule no nosso arquivo de app.module.ts

App Module

Aqui no arquivo acima, habilitamos o middleware apenas para o path items e o requisições do tipo GET.

Exception Filters

O nest tem algo bem bacana aqui que seria o Exception Filters, ele vem com uma camada de exceções integrada, que é responsável por processar todas as exceções não tratadas no app. Quando isso acontece, o erro é capturado por essa camada, que envia automaticamente uma resposta amigável para o usuário que está chamando o serviço.

Exception Filter
Exception Filter

Caso você queira lidar com as exceções, você poderá configurar o seu próprio filtro de exceções. Para isso crie uma classe que implementa a ExceptionFilter, e adicione a sua lógica para o tratamento.

Exception Filter

Aqui no código acima você utiliza o decorator @Catch(HttpException), com isso você informa ao nest que esse filtro específico, apenas aceita exceções do tipo HttpException e nada além disso. Esse decorator pode receber um parâmetro ou uma lista separado por vírgula, tratando vários tipos de exceções de uma só vez.

Agora você poderá definir a utilização do filter, utilizando o decorator @UseFilters(HttpExceptionFilter) no seu Controller. Ou por método (method-scoped) ou pela classe (controller-scoped).

Items Controller

Também podemos defini-lo como global no arquivo main.ts, ou no arquivos module (global-scoped). Assim será aplicado em todo app (todas rotas e controllers).

Main
App Module

Pipes

Os Pipes são classes que utiliza o decorator @Injectable() e que implementam a interface PipeTransform.

Pipes
Pipes

Eles tem duas utilidades:

  • Transformação: transforma os dados de entrada no formato desejado (ex: string para int)
  • Validação: verifica se os dados de entrada são válidos, caso contrário lança uma exceção.

O nest já vem com alguns pipes e você pode utilizá-los, são eles: ValidationPipe, ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseArrayPipe, ParseUUIDPipe, ParseEnumPipe, DefaultValuePipe, ParseFilePipe.

Você pode definir os pipes em: argumento da rota, métodos, controllers ou então globalmente.

Items Controller
Main
App Module

Guards

Os Guards têm uma única responsabilidade, determinar se uma solicitação será tratada pelo handler de rotas ou não, dependendo de algumas condições (permissões, funções, ACLs, etc.) no momento da execução.

Ao contrário dos middlewares que não sabem sobre o próximo passo (next()) na cadeia, os guards sabem exatamente o que será executado em seguida.

Guard
Guard

Para criar um guard você deverá implementar a interface CanActivate e utilizar o decorator @Injectable(). Os guards são executados após todos middlewares, porém antes dos interceptores e pipes.

Um ótimo exemplo para utilização de guards seria autorização, pois você poderá definir que as rotas sejam validadas com a autenticação enviada.

Como nas pipes, os guards também podem ser definidos em: controllers, métodos, ou globalmente.

Interceptors

O Interceptor possui um conjunto de recursos bem úteis, o que faz que com ele seja possível realizar:

  • Vincular uma lógica antes ou depois da execução do método.
  • Transformar o resultado retornado.
  • Transformar a exceção lançada.
  • Estender o comportamento da função.
  • Substituir uma função completamente dependendo de certas condições (ex: cache)
Interceptor
Interceptor

Para criar um interceptor, é necessário criar uma classe e utilizar o decorator @Injectable() e implementar a interface NestInterceptor.

No exemplo acima usamos para alterar o retorno, quando for null, trocamos por uma string vazia (‘’) .

Aqui também podemos definir os interceptors em: controllers, métodos, ou globalmente.

Concluindo…

Aqui aprendemos sobre como criar serviços backends eficientes com NestJS, utilizando injeção de dependência. E com a facilidade de criação de rotas utilizando seus decorators. E ainda contamos com o suporte a Typescript que nos auxilia no desenvolvimento, e reduz o número de bugs. 😃

Você pode aprender mais sobre Nest com a documentação oficial deles clicando aqui.

--

--