Erros comuns em NestJS que você deve evitar
Práticas objetivas, baseadas em experiência, para manter seu backend estável, legível e de fácil manutenção.
1) Módulos: importações, exportações e ciclos
Em NestJS, a arquitetura modular determina como provedores, controladores e middlewares se conectam. Erros comuns surgem quando os módulos não exportam o que precisa ser utilizado por outros módulos, abrindo espaço para dependências difíceis de rastrear e mudanças acidentais em cascata.
- Exportar provedores que precisam ser usados externamente: AuthService, UserRepository, etc.
- Importar apenas as dependências necessárias; minimize acoplamento entre módulos por domínio.
- Evitar ciclos de dependência. Se AuthModule depende de UserModule e vice-versa, prefira reestruturar ou usar forwardRef com parcimônia.
- Quando possível, mantenha cada módulo com responsabilidade bem definida e com interfaces estáveis.
2) Injeção de dependências: providers, escopo e singleton
A injeção de dependências é o pilar da reusabilidade. Problemas aparecem quando dependências são criadas manualmente ou quando o escopo não é entendido.
- Use @Injectable() e injeção por construtor. Evite instanciar classes com new dentro de serviços.
- O escopo padrão é Singleton. Alterar para REQUEST ou TRANSIENT deve ter justificativa clara para evitar estados compartilhados inesperados.
- Considere tokens de providers para abstrações; mantenha os módulos testáveis e substituíveis.
- Evite dependências globais sem necessidade; isole o comportamento por domínio.
3) Tratamento de erros: exceções, filtros e validação
Erros não tratados ou mensagens confusas costumam retornar clientes uma experiência ruim. NestJS oferece exceções herdadas de HttpException e filtros de exceção para padronizar respostas. Centralizar ações de erro facilita debugging e observabilidade sem perder a clareza nas respostas para o consumidor da API.
- Leve e clara a resposta de erro. Use estados HTTP adequados (404, 400, 409, etc.).
- Não silencie exceções inesperadas; permita que logs capturem o essencial para diagnóstico.
- Considere filtros globais para formatação consistente, especialmente em cenários de múltiplos serviços.
- Combine com validação para apontar rapidamente o que está errado no payload.
4) Validação e transformação de DTOs
A validação de entradas via DTOs com class-validator/class-transformer reduz ruído e evita estados inconsistentes no serviço. Ative globalmente o ValidationPipe para manter o contrato de entrada da API e transformar dados quando necessário.
Exemplo de DTO e uso básico com validação integrada:
// main.ts (configuração global)
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// whitelist transforma, remove campos não declarados e retorna 400 se houver campos não permitidos
app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }));
await app.listen(3000);
}
bootstrap();
// dto e controller (example)
import { IsString, IsInt, Min } from 'class-validator';
export class CreateUserDto {
@IsString()
name: string;
@IsInt()
@Min(0)
age: number;
}
import { Controller, Post, Body } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Post()
async create(@Body() dto: CreateUserDto) {
// lógica de criação
return { ok: true, user: dto };
}
}
Benefícios dessa abordagem:
mensagens de erro padronizadas, payloads limpos após whitelist e transformação automática para tipos esperados no código.