Engenharia de IA Aplicada à Programação Web
Aula 1 de 8
Navegar por módulos e aulas
  1. 01 Fundamentos da Web
  2. 02 JavaScript moderno
  3. 03 TypeScript, Git e qualidade
  4. 04 Angular
  5. 05 Node.js, NestJS e APIs
  1. 5.1 Introdução ao Node.js e NestJS
  2. 5.2 Módulos, controladores e provedores
  3. 5.3 REST, rotas e respostas HTTP
  4. 5.4 DTOs, pipes e validação
  5. 5.5 Erros, filtros e configuração
  6. 5.6 OpenAPI e documentação
  7. 5.7 Registros, interceptadores e testes
  8. 5.8 Compilação e projeto final

Módulo 5 · Aula 5.1

Introdução ao Node.js e NestJS

2 horas Teoria + laboratório Node.js, NestJS e APIs
Ver fonte Markdown

Identificação

Introdução

O que é back-end?

Back-end é a parte do sistema executada em um ambiente controlado pelo responsável da aplicação. Ele recebe requisições, valida dados, aplica regras, verifica permissões e conversa com serviços como MySQL.

Angular no navegador → HTTP → back-end → Prisma → MySQL

O navegador não deve receber senha do banco nem executar regras críticas sozinho.

O que é Node.js?

Node.js é um ambiente de execução, ou ambiente de execução, que permite executar JavaScript fora do navegador. Ele é aberto, multiplataforma e inclui APIs para arquivos, processos, rede e servidores.

node app.js

Node.js não é uma linguagem. A linguagem continua sendo JavaScript; neste curso, escreveremos principalmente TypeScript e o transformaremos em JavaScript executável.

Node.js é um servidor?

Não por si só. Node.js consegue criar um servidor, executar um script de linha de comando, processar uma fila ou rodar testes. Um programa Node se torna servidor quando abre uma porta e passa a aceitar conexões.

Node.js é igual a JavaScript do navegador?

Não. A linguagem central é a mesma, mas o ambiente oferece APIs diferentes.

Navegador Node.js
possui DOM e document não possui DOM por padrão
controla a interface controla processo e servidor
código chega ao usuário código fica no servidor
não guarda segredos pode ler segredos do ambiente

O que é ambiente de execução?

Ambiente de execução é o ambiente que executa o programa. O navegador é um ambiente de execução para a Web; Node.js é um ambiente de execução para aplicações fora do navegador.

O que é um processo?

Processo é uma instância do programa em execução no sistema operacional. Quando iniciamos a API, o sistema cria um processo Node com memória, identificador, diretório atual e variáveis de ambiente.

console.log(process.pid);
console.log(process.cwd());
console.log(process.env.NODE_ENV);

Encerrar o terminal normalmente encerra o processo iniciado nele. Em produção, um orquestrador ou serviço gerencia reinício e desligamento.

O que é uma porta?

Porta é um número que ajuda o sistema operacional a entregar uma conexão ao processo correto. O endereço abaixo combina protocolo, host e porta:

http://localhost:3000
│      │         └── porta
│      └──────────── host
└─────────────────── protocolo

Dois processos não podem escutar a mesma combinação de endereço e porta ao mesmo tempo.

O que é localhost?

É um nome que aponta para a própria máquina. Uma API em localhost:3000 é acessível localmente, mas não está automaticamente publicada na internet.

O que é npm?

npm é o gerenciador de pacotes que acompanha instalações comuns do Node.js. Ele lê o package.json, instala dependências e executa scripts.

npm install
npm run start:dev

npm não é Node.js nem NestJS. Ele ajuda a obter e executar as ferramentas do projeto.

O que é package.json?

É o manifesto do projeto Node. Ele registra nome, scripts e dependências.

{
  "name": "knowledge-api",
  "scripts": {
    "start:dev": "nest start --watch",
    "build": "nest build"
  }
}

Não edite node_modules manualmente; dependências são reproduzidas pelo manifesto e pelo arquivo de lock.

O que é NestJS?

NestJS é um framework para construir aplicações Node.js organizadas. Ele oferece estrutura modular, controllers, providers, injeção de dependência, validação, testes, OpenAPI e integração com plataformas HTTP.

NestJS não substitui Node.js: o framework roda sobre o ambiente de execução Node.

TypeScript → NestJS → adaptador HTTP → Node.js → sistema operacional

NestJS é igual a Express?

Não. Nest oferece uma arquitetura de aplicação e usa um adaptador HTTP por baixo. Express é o adaptador padrão; Fastify pode ser escolhido. Na maior parte do código, usamos abstrações do Nest para evitar acoplamento desnecessário ao adaptador.

NestJS é o Angular do back-end?

Eles compartilham ideias como decorators, módulos e injeção de dependência, o que facilita o aprendizado. Porém, Angular renderiza a interface no cliente e NestJS recebe requisições no servidor. Um não executa o papel do outro.

Consigo usar com XAMPP?

Sim, como arquitetura combinada:

Apache/XAMPP → entrega a compilação do Angular
Node.js      → executa a API NestJS na porta 3000
MySQL/XAMPP  → armazena dados a partir do Módulo 6

O Apache não executa NestJS como PHP. A API permanece em um processo Node separado.

O que é Nest CLI?

É a ferramenta de terminal que cria, executa, compila e gera partes da aplicação. Podemos usá-la sem instalação global:

npx @nestjs/cli@latest new knowledge-api --strict

Depois, os scripts do projeto utilizam a versão local das ferramentas:

cd knowledge-api
npm run start:dev

O que é inicialização?

Inicialização é a inicialização da aplicação. O arquivo main.ts cria uma instância Nest a partir do módulo raiz, aplica configurações e abre uma porta.

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix("api");
  await app.listen(3000);
}

void bootstrap();

Como isso entra na Knowledge AI?

Criaremos a primeira fronteira real do back-end:

GET /api/health
  → HealthController
  → HealthService
  → { status: "ok" }

Esse endpoint informa que o processo HTTP responde. Nesta aula, ele não acessa o MySQL e não deve afirmar que dependências futuras estão saudáveis.

Objetivos

Ao final da aula, o aluno deverá conseguir:

  1. explicar back-end, ambiente de execução, processo, host e porta;
  2. diferenciar Node.js, npm, TypeScript e NestJS;
  3. comparar código do navegador e do servidor;
  4. explicar a relação entre NestJS, Express e Fastify;
  5. criar um projeto NestJS estrito;
  6. reconhecer a estrutura inicial gerada;
  7. explicar main.ts e inicialização;
  8. criar módulo, controller e provider;
  9. utilizar injeção de dependência no controller;
  10. implementar GET /api/health;
  11. ler porta de uma variável de ambiente com fallback;
  12. explicar a integração com Angular, XAMPP e MySQL;
  13. testar o endpoint com navegador, curl ou cliente HTTP;
  14. evitar segredos e acesso ao banco no front-end.

Pré-requisitos

  • Módulos 1 a 4 concluídos;
  • TypeScript, módulos e async/await;
  • HTTP, requisição, resposta, JSON e status;
  • terminal básico;
  • Node.js instalado para executar o projeto real.

Pergunta orientadora

Como transformar um programa TypeScript em um processo HTTP organizado que responde ao Angular?

Roteiro sugerido

Etapa Duração
Node.js, processo e porta 25 min
npm, manifesto e dependências 20 min
NestJS, CLI e estrutura 25 min
Módulo, controller e provider 30 min
Laboratório 15 min
Revisão 5 min

1. Verificando o ambiente

node --version
npm --version

Use uma versão Node suportada pela versão do Nest selecionada. Registre a versão no README e no mecanismo de ambiente da equipe para evitar diferenças silenciosas.

2. Criando o espaço de trabalho

npx @nestjs/cli@latest new knowledge-api --strict

O comando cria arquivos e instala dependências. Em uma equipe, não use latest sem decisão: fixe e atualize versões com revisão.

3. Estrutura inicial

knowledge-api/
├── src/
│   ├── app.controller.ts
│   ├── app.controller.spec.ts
│   ├── app.module.ts
│   ├── app.service.ts
│   └── main.ts
├── test/
├── package.json
├── nest-cli.json
├── tsconfig.json
└── eslint.config.mjs

O CLI pode evoluir nomes e configurações entre versões. Entenda responsabilidades, não memorize somente a árvore.

4. Executando em desenvolvimento

npm run start:dev

O modo watch recompila e reinicia após alterações. Ele é para desenvolvimento, não um gerenciador de produção.

5. Processo e ciclo de vida

Enquanto listen mantém o servidor aberto, o event loop continua processando conexões, timers e tarefas assíncronas. Não execute cálculo pesado síncrono no caminho da requisição; ele pode bloquear outras conexões do processo.

6. Configurando a porta

const port = Number(process.env.PORT ?? 3000);

if (!Number.isInteger(port) || port < 1 || port > 65_535) {
  throw new Error("PORT inválida");
}

Valores de process.env chegam como strings ou undefined. Faça conversão e validação explícitas.

7. Inicialização completa da aula

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap(): Promise<void> {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix("api");

  const port = Number(process.env.PORT ?? 3000);
  await app.listen(port);
  console.log(`Knowledge API disponível em http://localhost:${port}/api`);
}

void bootstrap();

Em produção, prefira o logger estruturado a console.log e trate desligamento gracioso conforme a plataforma.

8. O que é decorator?

Decorator adiciona metadados a uma classe, método ou parâmetro. O Nest lê esses metadados para montar módulos, rotas e dependências.

@Controller("health")
export class HealthController {}

O nome do arquivo não cria a rota. São os decorators registrados em um módulo que formam o mapa da aplicação.

9. Módulo raiz

import { Module } from "@nestjs/common";
import { HealthModule } from "./health/health.module";

@Module({
  imports: [HealthModule],
})
export class AppModule {}

AppModule é o ponto inicial do grafo. Ele não precisa concentrar todos os controllers e providers.

10. Módulo de capacidade

@Module({
  controllers: [HealthController],
  providers: [HealthService],
})
export class HealthModule {}

O módulo agrupa elementos relacionados. imports, controllers, providers e exports possuem responsabilidades distintas.

11. Controller

Controller recebe requisições e envia respostas. Ele escolhe a rota e delega regra ao provider.

@Controller("health")
export class HealthController {
  constructor(private readonly healthService: HealthService) {}

  @Get()
  check(): HealthResponse {
    return this.healthService.check();
  }
}

Com prefixo global api, a rota final é GET /api/health.

12. Provider

Provider é uma dependência gerenciada pelo container do Nest. Services são providers comuns, mas qualquer classe ou valor configurado pode ser provider.

@Injectable()
export class HealthService {
  check(): HealthResponse {
    return {
      status: "ok",
      service: "knowledge-api",
      timestamp: new Date().toISOString(),
    };
  }
}

@Injectable() informa que a classe participa da injeção de dependência.

13. Injeção de dependência

O controller declara o que precisa e o container fornece a instância registrada:

HealthModule registra HealthService
       ↓
container cria HealthService
       ↓
container injeta no HealthController

Evite new HealthService() no controller; isso ignora o container e dificulta testes e substituições.

14. Contrato da resposta

export interface HealthResponse {
  readonly status: "ok";
  readonly service: "knowledge-api";
  readonly timestamp: string;
}

A interface ajuda o compilador, mas não valida entrada externa. Aqui o servidor cria o objeto; DTOs e validação de requisição serão aprofundados na Aula 5.4.

15. Serialização automática

Ao retornar um objeto pela abordagem padrão, o Nest o serializa como JSON e responde 200 para o GET.

{
  "status": "ok",
  "service": "knowledge-api",
  "timestamp": "2026-08-01T12:00:00.000Z"
}

Evite acessar diretamente o objeto nativo de resposta sem necessidade; isso acopla o controller ao adaptador HTTP.

16. Requisição completa

GET /api/health HTTP/1.1
Host: localhost:3000
Accept: application/json

Resposta:

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"ok","service":"knowledge-api","timestamp":"..."}

17. Testando com navegador

Abra:

http://localhost:3000/api/health

O navegador é suficiente para GET simples. Para outros métodos e headers, use curl, cliente HTTP ou teste automatizado.

18. Testando com curl

curl -i http://localhost:3000/api/health

-i mostra status e headers junto do corpo.

19. Testando no PowerShell

Invoke-RestMethod -Uri 'http://localhost:3000/api/health'

O comando converte JSON em objeto PowerShell. Use Invoke-WebRequest quando precisar inspecionar a resposta HTTP de outra forma.

20. Angular consumindo a API

readonly health = httpResource<HealthResponse>(
  () => "http://localhost:3000/api/health",
);

Em projeto real, centralize a URL pública e configure CORS ou proxy de desenvolvimento. Não espalhe endereços por componentes.

21. XAMPP e portas

Uma configuração local possível:

Processo Endereço comum
Apache/XAMPP http://localhost ou porta 80
Angular em desenvolvimento http://localhost:4200
NestJS http://localhost:3000
MySQL/XAMPP porta 3306, sem acesso pelo navegador

Portas podem mudar. A configuração deve ser explícita e não conflitar.

22. CORS não é autenticação

Se Angular e NestJS usam origens diferentes, o navegador aplica CORS. Permitir uma origem não autentica o usuário nem autoriza ações.

app.enableCors({
  origin: ["http://localhost:4200"],
});

Use uma allowlist configurada. Não libere qualquer origem junto com credenciais sem entender o risco.

23. Variáveis de ambiente

PORT=3000
NODE_ENV=development

Variáveis configuram o processo. Arquivos .env com segredos não devem entrar no Git. A biblioteca de configuração e validação será tratada na Aula 5.5.

24. O endpoint de saúde não é banco

Nesta aula, status: "ok" significa apenas que o processo respondeu. Quando houver MySQL, poderemos separar:

liveness  → processo está vivo?
readiness → dependências necessárias estão prontas?

Não faça uma consulta pesada ao banco em toda verificação de vida.

25. Erros de inicialização

Falhas comuns:

  • porta já está em uso;
  • Node incompatível;
  • dependências não instaladas;
  • import incorreto;
  • provider ausente no módulo;
  • variável de ambiente inválida;
  • compilação TypeScript falhou.

Leia a primeira causa útil do registro, não apenas a última linha.

26. Código síncrono bloqueante

Node é eficiente para I/O concorrente, mas um cálculo síncrono longo bloqueia o event loop daquele processo. CPU intensa deve ser dividida, movida para worker ou executada fora do caminho da requisição conforme a arquitetura.

27. Tratando desligamento

Em produção, o processo pode receber sinal para encerrar. Ele deve parar de aceitar trabalho, concluir operações permitidas e fechar recursos dentro do prazo da plataforma. Não dependa apenas de fechar o terminal manualmente.

28. Scripts principais

{
  "scripts": {
    "start": "nest start",
    "start:dev": "nest start --watch",
    "build": "nest build",
    "test": "vitest run"
  }
}

Execute scripts com npm run. Eles usam as ferramentas instaladas no projeto e ajudam a manter versões consistentes entre pessoas e CI.

29. Laboratório guiado

Abra o simulador do ciclo da API.

Etapa 1 — Inicie o processo

Observe ambiente de execução, PID simulado, ambiente e porta.

Etapa 2 — Envie GET /api/health

Acompanhe adaptador HTTP, roteamento, controller, provider, serialização e resposta.

Etapa 3 — Altere a porta

Compare uma porta válida, inválida e ocupada.

Etapa 4 — Solicite rota inexistente

Veja a diferença entre processo saudável e endpoint 404.

Etapa 5 — Pare o processo

Confirme que nenhuma requisição pode ser atendida sem servidor em execução.

Etapa 6 — Examine as fontes

Compare main.ts, módulo, controller e service equivalentes.

30. Sobre o laboratório estático

O laboratório não inicia um servidor real nem abre portas. Ele simula o ciclo para funcionar diretamente pelo XAMPP. A pasta src contém a aplicação NestJS equivalente que pode ser copiada para um espaço de trabalho criado pelo CLI.

31. Erros comuns

Achar que Node.js é linguagem

JavaScript/TypeScript são linguagens; Node é o ambiente de execução.

Achar que npm executa o servidor

npm localiza o script; o processo final é Node executando o código compilado.

Executar NestJS dentro do Apache

Apache e Node são processos diferentes. Eles podem trabalhar juntos por HTTP.

Acessar MySQL pelo Angular

Credenciais e regras ficariam expostas. O Angular chama a API NestJS.

Criar service com new

Isso ignora o container de injeção.

Colocar regra no controller

Controller deve traduzir HTTP e delegar comportamento.

Usar qualquer porta sem validar

Strings inválidas e conflitos impedem a inicialização.

Publicar modo watch

start:dev prioriza desenvolvimento. Produção exige compilação e gerenciamento de processo.

Colocar segredo no registro

Registros podem persistir. Não registre tokens, senhas ou conexão MySQL.

32. Exercício de fixação

Crie um InfoModule com:

  • GET /api/info;
  • InfoController;
  • InfoService;
  • nome e versão vindos de configuração pública;
  • tipo de resposta;
  • teste que verifica status e corpo;
  • ausência de segredo na resposta.

Desenhe o caminho completo da requisição.

33. Desafio individual

Amplie o health check com dois endpoints:

GET /api/health/live
GET /api/health/ready

Modele estados ok e degraded, duração e versão, sem conectar ainda ao MySQL. Explique quais dependências futuras pertencerão ao readiness e como evitar sobrecarga.

34. Lista de verificação de conclusão

  • Sei explicar ambiente de execução e processo.
  • Distingo Node.js, npm, NestJS e TypeScript.
  • Sei o que host e porta representam.
  • Entendo a relação NestJS, Express e Fastify.
  • Consigo explicar main.ts e inicialização.
  • Distingo módulo, controller e provider.
  • Uso injeção de dependência.
  • Implementei GET /api/health.
  • Sei executar e parar o servidor.
  • Não envio credenciais MySQL ao Angular.

35. Critérios de avaliação

Critério Pontos
Explicação de Node, ambiente de execução e processo 20
Inicialização e configuração da porta 15
Organização do módulo 15
Controller e rota 15
Provider e injeção 15
Contrato HTTP 10
Segurança, teste e explicação 10
Total 100

36. Resumo

  • Node.js executa JavaScript fora do navegador;
  • um servidor é um programa que escuta uma porta;
  • npm gerencia pacotes e scripts;
  • NestJS organiza aplicações Node com módulos e DI;
  • controller recebe HTTP e provider concentra comportamento;
  • main.ts inicializa a aplicação;
  • XAMPP, Angular, NestJS e MySQL rodam como partes separadas;
  • o health check desta aula verifica apenas o processo HTTP.

37. Fontes oficiais

Próxima aula

Na Aula 5.2, aprofundaremos módulos, controllers, providers, exports e organização por capacidade ao criar o módulo de tarefas.