Arquitetura e Tecnologias
Entenda como as tecnologias se relacionam, o fluxo de requisições, cache e acesso aos bancos de dados.
Stack Tecnológico
Framework
- NestJS 11.x
- TypeScript
- Node.js
Bancos de Dados
- MongoDB (Mongoose + pool)
- PostgreSQL (TypeORM + pool)
Cache & Mensageria
- Redis (ioredis)
- Apache Kafka
Storage & APIs
- MinIO (S3 Compatible)
- GraphQL (Apollo)
- REST API
Autenticação
- JWT (Passport)
- Argon2id
- Login social
- Active Directory
Serviços
- Graylog (Logging GELF)
- SMTP / MailHog (Email)
- WhatsApp (Evolution API)
- Terminus (/health)
Configurações e Environment Variables
Todas as configurações são centralizadas através de arquivos de config em src/config/ e acessadas via ConfigService. As variáveis de ambiente são carregadas automaticamente.
Arquivos de Config
app.config.ts- Configurações da aplicaçãodatabase.config.ts- MongoDB e PostgreSQL (inclui pool)redis.config.ts- Cache Rediskafka.config.ts- Mensageria Kafkajwt.config.ts- Autenticação JWTargon2.config.ts- Hash de senhasgoogle-oauth.config.ts- Google OAuth2facebook-oauth.config.ts- Facebook OAuth2twitter-oauth.config.ts- X / Twitter OAuth2 (PKCE)github-oauth.config.ts- GitHub OAuth2figma-oauth.config.ts- Figma OAuth2linkedin-oauth.config.ts- LinkedIn OpenID Connectslack-oauth.config.ts- Slack OpenID Connectatlassian-oauth.config.ts- Atlassian OAuth 2.0 (3LO)gitlab-oauth.config.ts- GitLab OAuth2bitbucket-oauth.config.ts- Bitbucket OAuth2discord-oauth.config.ts- Discord OAuth2twitch-oauth.config.ts- Twitch OAuth2steam-openid.config.ts- Steam OpenID 2.0reddit-oauth.config.ts- Reddit OAuth2amazon-oauth.config.ts- Amazon Login with Amazonpatreon-oauth.config.ts- Patreon OAuth2dropbox-oauth.config.ts- Dropbox OAuth2metamask-auth.config.ts- MetaMask SIWE (EIP-4361)ad-ldap.config.ts- Active Directory LDAP/LDAPS (AD DS on-prem)apple-oauth.config.ts- Apple Sign In (OIDC form_post)smtp.config.ts- Email SMTPminio.config.ts- Storage MinIOgraylog.config.ts- Logging Graylog (GELF)graphql.config.ts- GraphQLwhatsapp.config.ts- WhatsApp API
Exemplo de Uso
constructor(private configService: ConfigService) {}
// Acessar configuração
const mongoUri = this.configService.get('database.mongoUri');
const redisHost = this.configService.get('redis.host');
const jwtSecret = this.configService.get('jwt.secret');
Fluxo de Requisição
1. Cliente faz requisição HTTP
Requisição chega ao servidor NestJS com headers (Authorization, Content-Type, etc.)
2. Security (IP / catch-all)
SecurityModule registra rotas de API inválidas e pode bloquear IPs (catch-all em production/staging). API admin em /api/v1/security — veja a página Security.
3. Autenticação JWT
JwtAuthGuard valida o token JWT. Rotas marcadas com @Public() são ignoradas.
4. Autorização por Roles
RolesGuard verifica se o usuário possui as roles necessárias definidas via @Roles()
5. Interceptor de Cache
TypeOrmCacheInterceptor ou MongooseCacheInterceptor verifica se há dados em cache no Redis
6. Controller/Resolver
Requisição chega ao controller (REST) ou resolver (GraphQL)
7. Service Layer
Lógica de negócio é executada no service, que utiliza repositories para acesso a dados
8. Repository Pattern
O service do módulo injeta o repositório escolhido — PostgreSQL (TypeORM) e/ou MongoDB (Mongoose) — conforme a necessidade do domínio. Os dois repositórios por domínio permitem um único banco ou CQRS (commands em um, queries em outro).
9. Logging (Graylog)
Interceptor e exception filter enviam logs estruturados em GELF para o Graylog (quando GRAYLOG_ENABLED=true).
10. Resposta e Cache
Dados são retornados ao cliente e, se aplicável, armazenados no Redis para próximas requisições
Sistema de Cache
Como Funciona
O sistema de cache utiliza Redis como camada intermediária para armazenar resultados de consultas frequentes, reduzindo a carga nos bancos de dados e melhorando o tempo de resposta.
Interceptors de Cache
TypeOrmCacheInterceptor- Cache para consultas TypeORM (PostgreSQL)MongooseCacheInterceptor- Cache para consultas Mongoose (MongoDB)CacheService- Serviço centralizado para gerenciar cache
Configuração Redis
REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD= REDIS_DB=0 REDIS_TTL=3600 # Time to Live em segundos
Fluxo de Cache
- Requisição chega ao interceptor de cache
- Interceptor verifica se existe chave no Redis
- Se existe: retorna dados do cache (cache hit)
- Se não existe: executa query no banco, armazena no Redis e retorna (cache miss)
- Dados expiram automaticamente após TTL configurado
Persistência: Mongo, Postgres e CQRS-ready
Padrão do template
O template mantém MongoDB e PostgreSQL no stack. Cada domínio pode ter dois repositórios; o service escolhe um banco ou ambos (CQRS). Não há split command/query obrigatório — a escolha é por módulo.
Connection pools
Ambas as conexões usam pool explícito (config em database.config.ts). O endpoint GET /health inclui metadados do pool nos checks de postgres e mongo.
POSTGRES_POOL_MAX=10 POSTGRES_POOL_MIN=2 POSTGRES_POOL_IDLE=30000 POSTGRES_POOL_TIMEOUT=5000 MONGO_POOL_MAX=10 MONGO_POOL_MIN=0 MONGO_POOL_IDLE=30000 MONGO_POOL_TIMEOUT=5000
PostgreSQL
- • Schema relacional e tipado (TypeORM)
- • Repository:
ResourcePostgresRepository - • Use como única fonte de verdade ou como lado de queries em CQRS
MongoDB
- • Schema flexível e documental (Mongoose)
- • Repository:
ResourceMongoRepository - • Use sozinho ou como lado de commands em CQRS
Exemplo: um banco só
constructor(
private readonly postgresRepo: ResourcePostgresRepository,
) {}
async create(data: CreateResourceDto) {
return this.postgresRepo.create(data);
}
async findAll() {
return this.postgresRepo.findAll();
}
Exemplo: ativar CQRS
Injete ambos os repositórios no service: commands em um banco, queries no outro. Opcionalmente sincronize com Kafka para consistência eventual.
constructor(
private readonly mongoRepo: ResourceMongoRepository, // commands
private readonly postgresRepo: ResourcePostgresRepository, // queries
) {}
async create(data: CreateResourceDto) {
const resource = await this.mongoRepo.create(data);
// publicar evento Kafka para projetar no Postgres...
return resource;
}
async findAll() {
return this.postgresRepo.findAll();
}
Mongo ou Postgres
Você pode usar só Postgres, só Mongo, ou ambos (CQRS). A escolha é no service/módulo, sem remover a infraestrutura do outro banco do projeto.
Como as Tecnologias se Relacionam
Diagrama de Relacionamento
Framework Core
Disponível / CQRS
Persistência / queries
Cache
Mensageria
Storage
Logs GELF
- NestJS ↔ MongoDB/PostgreSQL: Framework se comunica com bancos através de Mongoose e TypeORM; o service escolhe qual repositório usar
- NestJS ↔ Redis: Cache interceptors utilizam Redis para armazenar resultados
- NestJS ↔ Kafka: Eventos e mensagens são publicados/consumidos via Kafka (útil para projetar dados em CQRS)
- NestJS ↔ MinIO: Upload e download de arquivos via API S3-compatible
- NestJS ↔ Graylog: Logs estruturados via GELF HTTP (interceptor + exception filter)
- MongoDB ↔ PostgreSQL (opcional): Em um desenho CQRS, sincronização via eventos Kafka ou processos assíncronos