E aí, pessoal! Tudo certo? Bora começar uma série de posts sobre NestJS? A ideia aqui é criar um serviço bem simples de gerenciamento de tarefas, tipo um ToDo List mesmo. E, óbvio, vamos usar várias coisas que a gente usa todo dia quando tá construindo serviços.
O que é NestJS
NestJS é um framework top para criar aplicações em NodeJS com TypeScript. Ele é super modular e extensível. Para o servidor HTTP, ele usa o famoso ExpressJS. Mas, se você precisa de alta performance, pode ir de Fastify!
As features mais legais do Nest são a criação de módulos, injeção de dependências, uso de decorators e a facilidade para extender o código. No ecossistema, tem pacotes pra tudo: banco de dados (MySQL, Postgres, MongoDB), filas, microserviços. Borá começar!
Começando com o NestJS
Para criar nossso serviço, primeiro é necessário instalar o Nest CLI.
# pnpm
pnpm add -g @nestjs/cli
# npm
npm install -g @nestjs/cli
# yarn
yarn global add -g @nestjs/cli
Após instalar o Nest CLI, vamos criar nosso projeto em Nest:
nest new todo-list-service
Será solicitado qual gerenciado de pacotes você deseja usar. Eu particulamente prefiro o pnpm
, por ser mais rápido que os outros. Após a conclusão do processo, você deverá ver dentro da pasta o projeto criado com essa estrutura:
todo-list-service
|- src
|- app.controller.spec.ts
|- app.controller.ts
|- app.module.ts
|- app.service.ts
|- main.ts
|- tests
|- package.json
|- package-lock.json
|- tsconfig.json
|-...configuration-files
Primeiro endpoint
Quando o projeto é criado, é criado os arquivos main.ts, app.module.ts, app.controller.ts e app.service.ts. O arquivo main.ts
é onde a aplicação é criada e iniciada. Isso acontece dentro do metódo bootstrap
. Para criar a aplicação, é chamado o AppModule
que é uma classe implementada no arquivo app.module.ts. Nessa classe com o decorator @Module()
definimos quem são os controllers da nossa aplicação e quais são os providers. Além disso, é possível importar outros modulos.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController], // Controllers should be imported here
providers: [AppService], // Providers should be imported here
})
export class AppModule {}
Para criar um endpoint, podemos ir no arquivo app.controller.ts
. Nesse arquivo temos uma classe AppController com o decorator @Controller()
. Cada endpoint é um método dessa classe com alguns desses decorators: @Get()
, @Post
, @Put
, @Delete
, @Patch
, @Head
, @Options
, @Trace
.
Quando a aplicação é criada, já temos um GET
em /
que retorna um Hello World!
. Vamos adicionar mais um GET
que será nosso healthcheck:
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
// Alrealdy implemented
@Get()
getHello(): string {
return 'Hello World!';
}
@Get('health')
getHealth() {
return { status: 200, message: 'UP' };
}
}
Dentro do decorator @Controller
e nos decorators que mapeiam o verbo HTTP, podemos definir qual será a rota.
Por exemplo, caso tivessemos uma api de to-do’s, o controller poderia ser @Controller("todos")
. Todo método mapeado como http request, irá responder usando a rota que começa com /todos
. No get que busca um todo por id, no decorator get ficaria @Get(":id")
e a rota final seria /todos/:id
.
No caso do decorator controller estiver sem nenhum prefixo, então a rota irá responder a partir do root /
.
Rodando o serviço
Agora que já criamos nosso primeiro endpoint, vamos rodar o serviço e fazer um get na api. Para rodar o serviço, vamos usar o script start:dev
definido no package.json e chamar com algum gerenciador de pacotes do node:
# pnpm
pnpm start:dev
# npm
npm run start:dev
# yarn
yarn start:dev
Você deve ver algo assim no terminal:
[12:43:37 PM] File change detected. Starting incremental compilation...
[12:43:37 PM] Found 0 errors. Watching for file changes.
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [NestFactory] Starting Nest application...
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [InstanceLoader] AppModule dependencies initialized +2ms
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [RoutesResolver] AppController {/}: +0ms
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [RouterExplorer] Mapped {/, GET} route +0ms
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [RouterExplorer] Mapped {/error, POST} route +0ms
[Nest] 3173 - 02/07/2025, 12:43:38 PM LOG [NestApplication] Nest application successfully started +0ms
A porta default do Nest é a 3000. Então provalmente o serviço irá responder chamadas http na url http://localhost:3000
. Com o serviço rodando, vamos fazer nossa primeira request no serviço. Para isso, só chamar via curl
:
curl -v http://localhost:3000/health
E você deve ver algo assim:
* Trying 127.0.0.1:3000...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /health HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Content-Type: application/json; charset=utf-8
< Content-Length: 29
< ETag: W/"1d-IDhexl3N5aiBtUkBl0nBxaLgj3A"
< Date: Fri, 07 Feb 2025 15:49:45 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
{"status":200,"message":"UP"}%
Muito bem! No próximo post vamos adicionar services e modules ao nosso serviço.
Gostou do artigo? Compartilhe nas redes sociais.