# Aula 5.1 - Introdução ao Node.js e NestJS

## Identificação

- **Duração:** 2 horas
- **Tipo:** teoria aplicada e laboratório
- **Entrega:** primeira API NestJS com `GET /api/health`
- **Laboratório:** [`../exemplos/aula-5.1/index.html`](../exemplos/aula-5.1/index.html)

## 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.

```text
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.

```bash
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.

```ts
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:

```text
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.

```bash
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.

```json
{
  "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.

```text
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:

```text
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:

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

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

```bash
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.

```ts
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:

```text
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

```bash
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

```bash
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

```text
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

```bash
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

```ts
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

```ts
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.

```ts
@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

```ts
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

```ts
@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.

```ts
@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.

```ts
@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:

```text
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

```ts
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.

```json
{
  "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

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

Resposta:

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

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

## 17. Testando com navegador

Abra:

```text
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

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

`-i` mostra status e headers junto do corpo.

## 19. Testando no PowerShell

```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

```ts
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.

```ts
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

```text
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:

```text
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

```json
{
  "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](../exemplos/aula-5.1/index.html).

### 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:

```text
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

- [Node.js: introdução](https://nodejs.org/learn)
- [Node.js: process](https://nodejs.org/api/process.html)
- [NestJS: primeiros passos](https://docs.nestjs.com/first-steps)
- [NestJS CLI](https://docs.nestjs.com/cli/overview)
- [NestJS: controllers](https://docs.nestjs.com/controllers)
- [NestJS: providers](https://docs.nestjs.com/providers)
- [NestJS: modules](https://docs.nestjs.com/modules)

## 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.
