Aula 17 - NestJS / Express com Arquitetura Modular e DI 🧱
Objetivo Pedagógico
Objetivo: Construção de aplicações corporativas escaláveis em Node.js com padrão Clean Architecture, Injeção de Dependências e módulos encapsulados.
📑 1. Fundamentos Teóricos & Análise Técnica
O desenvolvimento de backends em Node.js com Express puro frequentemente degenera em código espaguete com acoplamento severo, devido à ausência de uma estrutura arquitetural prescritiva. O NestJS resolve essa deficiência estrutural ao trazer padrões consolidados da engenharia corporativa (fortemente inspirados no Angular e Spring Boot) para o ecossistema Node.js com TypeScript.
A arquitetura do NestJS baseia-se em três pilares fundamentais: 1. Módulos (@Module): Unidades lógicas coesas que encapsulam controllers, providers e serviços, exportando estritamente os componentes que outros módulos podem consumir. 2. Controladores (@Controller): Camada de entrada responsável pelo tratamento de rotas HTTP, extração de parâmetros (@Param, @Body, @Query) e delegação da execução para a camada de serviço. 3. Provedores / Serviços (@Injectable): Classes que implementam regras de negócio puras, instanciadas e gerenciadas automaticamente pelo contêiner de Injeção de Dependências (DI) do NestJS.
Essa separação viabiliza a implementação de Arquitetura Limpa (Clean Architecture) e testes unitários com isolamento total via mocks.
📐 Arquitetura Conceitual & Diagrama de Fluxo
graph TD
Request["Requisição HTTP: POST /orders"] --> Controller["OrdersController (@Controller)"]
Controller --> Pipe["ValidationPipe (Zod / class-validator)"]
Pipe --> Service["OrdersService (@Injectable - DI)"]
Service --> Repo["OrdersRepository (Data Access)"]
Repo --> DB["Banco de Dados PostgreSQL"]
style Request fill:#e1f5fe,stroke:#01579b
style Controller fill:#fff3e0,stroke:#e65100
style Service fill:#e8f5e9,stroke:#2e7d32
style DB fill:#f3e5f5,stroke:#7b1fa2 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Inversão de Controle (IoC): O ciclo de vida dos serviços e suas dependências são administrados pelo contêiner de DI do NestJS. - Pipes de Validação Automática: Transformação e validação de DTOs antes de atingir a lógica do controlador. - Interceptors e Guards: Controle de autorização por papéis (@Roles) e manipulação declarativa de respostas. - Testabilidade Extrema: Substituição trivial de repositórios reais por implementações em memória nos testes com Test.createTestingModule.
🛠️ 2. Implementação Prática em Node.js, NestJS e TypeScript
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// users.service.ts (Serviço NestJS com Injeção de Dependência)
import { Injectable, NotFoundException } from '@nestjs/common';
export interface UserEntity { id: string; name: string; email: string; }
@Injectable()
export class UsersService {
private readonly users: Map<string, UserEntity> = new Map();
async findById(id: string): Promise<UserEntity> {
const user = this.users.get(id);
if (!user) {
throw new NotFoundException(`Usuário com ID ${id} não foi encontrado.`);
}
return user;
}
async create(user: UserEntity): Promise<UserEntity> {
this.users.set(user.id, user);
return user;
}
}
💡 Análise Passo a Passo do Código
- Decorador @Injectable: Registra a classe no contêiner IoC do NestJS como um provider elegível para injeção.
- Exceções HTTP Nativas:
NotFoundExceptioné capturada pelo Exception Filter global e serializada emHTTP 404 JSONpadronizado. - Separação de Preocupações: O serviço não manipula objetos de requisição HTTP (
req,res), focando puramente no domínio.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto