Se você já trabalha com desenvolvimento de software — ou está começando agora — provavelmente já ouviu falar sobre design patterns. Eles surgem para resolver problemas comuns de arquitetura e organização de código. Mas, em meio a padrões mais tradicionais como MVC, Repository ou Service Layer, um conceito tem ganhado cada vez mais espaço, principalmente em aplicações modernas: o Vertical Slice Pattern.
De forma simples, o Vertical Slice propõe que você organize seu sistema por funcionalidade e não por camadas técnicas. Em vez de ter pastas como controllers, services e repositories separadas globalmente, cada funcionalidade do sistema passa a ter tudo o que precisa em um único lugar. Isso inclui controller, service, DTOs, casos de uso e até validações.
Essa abordagem faz muito sentido em frameworks como o NestJS, onde é comum vermos projetos crescerem rapidamente e se tornarem difíceis de manter quando seguem apenas a separação clássica por camadas. Com Vertical Slice, cada feature vira praticamente um “mini-sistema” independente dentro da aplicação.
Ao longo deste artigo, você vai entender:
- O que é o Vertical Slice Pattern na prática
- Por que ele é diferente (e muitas vezes melhor) que arquiteturas tradicionais
- Quando usar (e quando não usar)
- Como aplicar Vertical Slice em um projeto NestJS, com exemplos simples
- Os principais benefícios para manutenção, testes e escalabilidade
Se você busca escrever código mais organizado, fácil de evoluir e alinhado com práticas modernas de arquitetura, esse padrão merece sua atenção.
O que é o Vertical Slice Pattern, na prática?
O Vertical Slice Pattern é um padrão de arquitetura que organiza o código por casos de uso ou funcionalidades, e não por camadas técnicas globais. Em vez de pensar o sistema como “controller → service → repository”, você passa a pensar em algo como: “criar usuário”, “listar pedidos”, “atualizar perfil”.
Cada uma dessas funcionalidades se torna um slice vertical do sistema. Esse slice contém tudo o que é necessário para aquela ação funcionar do início ao fim: endpoint, regra de negócio, validação, acesso a dados e respostas.
Em uma arquitetura tradicional, é comum ter algo assim:
src/
├── controllers/
├── services/
├── repositories/
└── dtos/
O problema é que, com o tempo, para entender ou alterar uma única funcionalidade, você precisa navegar por várias pastas diferentes. Isso aumenta o acoplamento mental, dificulta manutenção e torna mudanças simples mais arriscadas.
Com Vertical Slice, a organização muda completamente:
src/
└── users/
├── create-user/
│ ├── create-user.controller.ts
│ ├── create-user.service.ts
│ ├── create-user.dto.ts
│ └── create-user.module.ts
Perceba que tudo relacionado a criar usuário está no mesmo lugar. Isso deixa o código mais legível, mais fácil de testar e muito mais simples de evoluir.
Outro ponto importante: o Vertical Slice não elimina camadas, ele apenas muda a forma como elas são organizadas. Controllers, services e repositórios continuam existindo, mas agora vivem juntos, focados em um único objetivo.
Esse padrão conversa muito bem com conceitos como Clean Architecture, DDD (Domain-Driven Design) e CQRS, mas sem exigir que você implemente tudo de uma vez — o que é ótimo para quem está começando.
Vertical Slice vs Arquitetura Tradicional (MVC e camadas)
Para entender de verdade o valor do Vertical Slice Pattern, vale comparar com a arquitetura mais comum no dia a dia: a separação clássica por camadas, muito usada em MVC, Service Layer e variações semelhantes.
Na arquitetura tradicional, o código costuma ser organizado assim:
src/
├── controllers/
├── services/
├── repositories/
├── entities/
└── dtos/
Essa estrutura parece limpa no início, principalmente em projetos pequenos. O problema aparece quando o sistema cresce. Uma funcionalidade simples, como “atualizar perfil do usuário”, passa a depender de arquivos espalhados por várias pastas. Para entender o fluxo completo, você precisa abrir controller, service, DTO, repository e, às vezes, regras de validação em outros lugares.
No Vertical Slice, a lógica é invertida. O foco não está na tecnologia usada, mas na ação que o usuário executa:
src/
└── users/
├── update-profile/
│ ├── update-profile.controller.ts
│ ├── update-profile.service.ts
│ ├── update-profile.dto.ts
│ └── update-profile.module.ts
Aqui, tudo que envolve “atualizar perfil” está agrupado. Isso traz alguns benefícios claros:
- Menos tempo para entender uma funcionalidade
- Mudanças mais seguras, pois o impacto fica isolado
- Código mais fácil de remover ou refatorar
- Melhor leitura para quem entra novo no projeto
Outro ponto importante é que o Vertical Slice reduz o risco de criar services gigantes e genéricos, que acabam virando “Deus Services”, responsáveis por regras demais.
Já a arquitetura tradicional tende a incentivar reutilização excessiva e acoplamento entre funcionalidades que, na prática, não deveriam depender umas das outras.
Isso não significa que MVC esteja “errado”. Ele funciona bem em sistemas pequenos ou muito simples. Mas, à medida que a aplicação cresce, o Vertical Slice costuma escalar melhor, especialmente em times maiores ou projetos que evoluem rápido.
Quando usar (e quando não usar) o Vertical Slice Pattern
Apesar de todos os benefícios, o Vertical Slice Pattern não é uma solução mágica para qualquer tipo de projeto. Como todo padrão de arquitetura, ele faz mais sentido em certos contextos. Saber quando usar — e quando evitar — é fundamental para tomar boas decisões técnicas.
Quando o Vertical Slice faz muito sentido
O Vertical Slice é especialmente indicado quando:
- A aplicação tende a crescer
Se você sabe que o projeto vai ganhar novas funcionalidades com frequência, organizar o código por casos de uso evita que tudo vire um grande emaranhado de dependências. - O domínio do negócio é importante
Quando as regras de negócio são mais relevantes que a tecnologia em si, pensar em funcionalidades (ex: criar pedido, cancelar assinatura, gerar relatório) deixa o código mais alinhado com o problema real. - Você trabalha com NestJS, APIs ou microsserviços
O NestJS incentiva modularização, e o Vertical Slice se encaixa muito bem nesse modelo. Cada feature vira um módulo pequeno e isolado. - O time tem mais de uma pessoa
Times conseguem trabalhar em slices diferentes sem pisar no código um do outro, reduzindo conflitos e retrabalho.
Quando talvez não seja a melhor escolha
Por outro lado, o Vertical Slice pode não valer a pena quando:
- O projeto é muito pequeno ou temporário
Para APIs simples ou protótipos rápidos, a arquitetura tradicional pode ser mais rápida de implementar. - A equipe ainda está aprendendo conceitos básicos
Para quem está dando os primeiros passos em programação, entender camadas clássicas pode ser mais didático antes de avançar para padrões mais modernos. - Você força reutilização onde não precisa
Um erro comum é tentar compartilhar tudo entre slices. O Vertical Slice aceita duplicação pontual se isso mantiver funcionalidades independentes.
O ponto-chave aqui é: use Vertical Slice para organizar complexidade, não para criá-la. Ele brilha quando o sistema cresce, quando mudanças são constantes e quando clareza é mais importante que reaproveitamento extremo de código.
Como aplicar o Vertical Slice em um projeto NestJS
O NestJS é um dos frameworks que mais se beneficiam do Vertical Slice Pattern, porque ele já nasce com o conceito de módulos bem definido. Em vez de usar os módulos apenas para separar domínios grandes (como UsersModule ou AuthModule), o Vertical Slice propõe algo mais específico: um módulo por caso de uso.
Vamos imaginar uma funcionalidade simples: criar usuário.
Estrutura de pastas usando Vertical Slice
Uma possível organização ficaria assim:
src/
└── users/
└── create-user/
├── create-user.controller.ts
├── create-user.service.ts
├── create-user.dto.ts
└── create-user.module.ts
Cada pasta representa uma feature completa, e tudo o que ela precisa está ali. Isso facilita muito quando você precisa entender, alterar ou até remover uma funcionalidade inteira.
Controller focado em um único caso de uso
No Vertical Slice, o controller não é genérico. Ele existe para uma única ação:
// create-user.controller.ts
@Controller('users')
export class CreateUserController {
constructor(private readonly service: CreateUserService) {}
@Post()
create(@Body() dto: CreateUserDto) {
return this.service.execute(dto);
}
}
Perceba que o método já deixa claro o objetivo. Nada de controllers gigantes com dezenas de endpoints diferentes.
Service com responsabilidade bem definida
O service também fica simples e direto:
// create-user.service.ts
@Injectable()
export class CreateUserService {
execute(dto: CreateUserDto) {
// regra de negócio aqui
return { message: 'Usuário criado com sucesso' };
}
}
Nada de services genéricos como UserService com métodos para tudo. Cada service resolve um problema específico.
Módulo isolado e fácil de manter
// create-user.module.ts
@Module({
controllers: [CreateUserController],
providers: [CreateUserService],
})
export class CreateUserModule {}
Esse módulo pode ser importado no AppModule ou em um módulo de domínio maior, mantendo tudo bem organizado.
O grande ganho aqui é clareza. Quem entra no projeto entende rapidamente o que cada pasta faz, sem precisar caçar arquivos espalhados pelo código.
Benefícios do Vertical Slice no dia a dia de desenvolvimento
Quando o Vertical Slice Pattern é aplicado corretamente, os benefícios aparecem rápido no dia a dia do projeto. Não é algo apenas “bonito no papel”, mas uma abordagem que realmente facilita a vida de quem desenvolve e mantém o sistema.
Código mais fácil de entender
Um dos maiores ganhos é a legibilidade. Para entender uma funcionalidade, você não precisa navegar por várias pastas diferentes. Tudo está concentrado em um único lugar. Isso reduz o tempo de onboarding de novos devs e diminui aquela sensação de “onde fica essa regra mesmo?”.
Manutenção mais segura
Como cada slice é isolado, o risco de quebrar outras partes do sistema ao fazer uma alteração é bem menor. Você muda algo em “criar pedido”, por exemplo, e sabe exatamente onde o impacto acontece. Isso deixa o código mais previsível e confiável.
Testes mais simples
Testar funcionalidades fica mais natural. Cada slice pode ter seus próprios testes unitários e de integração, focados em um único caso de uso. Isso melhora a qualidade do código e facilita a automação de testes ao longo do tempo.
Evolução e refatoração sem dor
Quer mudar completamente a regra de uma funcionalidade? Ou até removê-la? Com Vertical Slice, isso é simples. Você mexe (ou apaga) uma pasta inteira, sem medo de efeitos colaterais inesperados em outras áreas do sistema.
Melhor trabalho em equipe
Em times maiores, diferentes pessoas podem trabalhar em slices diferentes sem conflito. Isso reduz retrabalho, melhora a produtividade e deixa o versionamento do código muito mais tranquilo.
No fim das contas, o Vertical Slice ajuda a manter o foco no que realmente importa: resolver problemas de negócio com código claro e organizado.
Erros comuns ao usar Vertical Slice (e como evitá-los)
O Vertical Slice Pattern resolve muitos problemas de organização, mas quando é mal aplicado, pode acabar criando novos. A boa notícia é que a maioria dos erros é comum e fácil de evitar quando você entende a proposta do padrão.
1. Criar slices grandes demais
Um erro frequente é transformar um slice em um “mini-monolito”. Por exemplo, colocar tudo relacionado a usuário dentro de um único slice: criar, atualizar, listar, deletar, autenticar, etc.
O ideal é que cada slice represente um único caso de uso. Se você percebe que uma pasta está crescendo demais, provavelmente ela deveria ser dividida em slices menores.
2. Forçar reutilização entre slices
Muita gente tenta reaproveitar services ou regras entre slices a qualquer custo. Isso vai contra a ideia do Vertical Slice. Aqui, duplicação controlada é aceitável, desde que ajude a manter funcionalidades independentes.
Se algo realmente precisa ser compartilhado, como um helper ou uma regra de domínio central, aí sim faz sentido extrair para um lugar comum.
3. Misturar camadas tradicionais sem critério
Outro erro comum é tentar aplicar Vertical Slice, mas ainda manter pastas globais como services ou controllers. Isso gera confusão e quebra o conceito principal do padrão.
Se você escolheu Vertical Slice, vá até o fim: controllers, services e DTOs devem viver dentro da feature, não espalhados pelo projeto.
4. Criar abstrações cedo demais
Criar interfaces, factories e abstrações complexas logo no início costuma ser desnecessário. Comece simples. Deixe o código evoluir naturalmente e só extraia abstrações quando houver um problema real a ser resolvido.
5. Esquecer o domínio do negócio
Vertical Slice não é apenas organização de pastas. Ele exige que você pense em ações do usuário e regras de negócio, e não apenas em tecnologia.
Evitar esses erros garante que o padrão realmente traga benefícios, em vez de complexidade desnecessária.
Vertical Slice, Clean Architecture, DDD e CQRS: como tudo se encaixa
Uma dúvida muito comum é: Vertical Slice substitui Clean Architecture, DDD ou CQRS? A resposta curta é não. Na prática, esses conceitos se complementam, desde que usados com bom senso.
Vertical Slice e Clean Architecture
A Clean Architecture fala sobre separação de responsabilidades, dependências apontando para o domínio e regras de negócio isoladas. O Vertical Slice não contradiz isso. Ele apenas muda como o código é organizado fisicamente.
Você ainda pode ter regras de negócio bem definidas, entidades claras e dependências controladas, só que agora tudo fica agrupado por caso de uso. Em vez de uma camada de “use cases” global, cada slice vira um pequeno use case independente.
Vertical Slice e DDD
O Domain-Driven Design combina muito bem com Vertical Slice, principalmente quando você pensa em ações do domínio, como “registrar pagamento”, “cancelar pedido” ou “ativar assinatura”.
Cada slice pode representar um comando do domínio, com linguagem clara e próxima do negócio. Isso ajuda a reduzir código genérico e deixa o sistema mais expressivo.
Vertical Slice e CQRS
O CQRS (Command Query Responsibility Segregation) é quase um par natural do Vertical Slice. Commands e Queries já são, por definição, casos de uso específicos.
Por exemplo:
CreateOrderCommandGetOrderByIdQuery
Cada um desses pode virar um slice independente, com seu próprio handler, validações e dependências.
O ponto de equilíbrio
O maior erro aqui é tentar usar tudo ao mesmo tempo, com complexidade máxima. Vertical Slice não exige DDD completo nem CQRS avançado. Você pode começar simples e ir adicionando conceitos conforme o projeto cresce.
A ideia central é sempre a mesma: organizar o código em torno do que o sistema faz, e não em torno da tecnologia usada.
Vertical Slice impacta performance e escalabilidade?
Uma dúvida comum, principalmente de quem está começando a estudar arquitetura, é se o Vertical Slice Pattern afeta performance ou escalabilidade da aplicação. A resposta direta é: não de forma negativa. Na maioria dos casos, o impacto é neutro ou até positivo.
Performance
Vertical Slice é um padrão de organização de código, não de execução. Ele não adiciona camadas extras, não cria processamento adicional e não muda a forma como o NestJS executa requisições.
Se sua aplicação está lenta, o problema dificilmente está no Vertical Slice. Normalmente, gargalos vêm de:
- Queries mal otimizadas
- Uso incorreto de cache
- Chamadas externas lentas
- Falta de controle de concorrência
O Vertical Slice, inclusive, pode ajudar a identificar esses problemas mais facilmente, já que cada funcionalidade está isolada e bem definida.
Escalabilidade do código
Onde o Vertical Slice realmente brilha é na escalabilidade do código, não necessariamente da infraestrutura. À medida que o sistema cresce, ele evita que o projeto vire um “monstro” difícil de entender.
Adicionar uma nova funcionalidade vira algo previsível:
- Criar uma nova pasta
- Implementar o caso de uso
- Conectar no módulo principal
Isso reduz o medo de mudanças e incentiva evolução contínua.
Escalabilidade da equipe
Outro ponto importante é a escala do time. Com slices bem definidos, diferentes pessoas conseguem trabalhar em paralelo sem conflitos constantes. Isso melhora a produtividade e reduz erros causados por dependências ocultas.
Pensando no longo prazo
Em sistemas grandes, clareza é tão importante quanto performance. Código difícil de entender gera bugs, atrasos e retrabalho. Vertical Slice ajuda a manter o projeto saudável ao longo do tempo.
Como migrar um projeto existente para Vertical Slice
Se você já tem um projeto em produção usando arquitetura tradicional, a boa notícia é: você não precisa reescrever tudo para adotar o Vertical Slice Pattern. A migração pode (e deve) ser feita de forma gradual.
Comece pelas novas funcionalidades
A forma mais segura de iniciar é aplicar Vertical Slice apenas em novas features. Sempre que surgir uma nova funcionalidade, você cria um slice vertical em vez de seguir o padrão antigo.
Com o tempo, o projeto passa a ter uma mistura de abordagens, o que é totalmente aceitável durante a transição.
Migre funcionalidades isoladas
Depois, você pode escolher funcionalidades mais simples ou menos críticas para migrar. Por exemplo:
- Um endpoint pouco usado
- Uma funcionalidade de leitura
- Um fluxo com poucas dependências
Extraia tudo relacionado a esse caso de uso e coloque dentro de um slice próprio. O objetivo não é perfeição, mas clareza.
Evite grandes refatorações de uma vez
Tentar migrar tudo de uma só vez costuma gerar riscos desnecessários. Mudanças grandes aumentam a chance de bugs e dificultam revisões de código.
O Vertical Slice funciona melhor quando adotado aos poucos, respeitando o ritmo do projeto e do time.
Mantenha contratos estáveis
Durante a migração, evite mudar:
- Rotas da API
- Contratos de entrada e saída
- Formatos de resposta
Assim, o comportamento externo do sistema continua o mesmo, mesmo que a organização interna mude.
Use a migração como aprendizado
A migração é uma ótima oportunidade para identificar:
- Código duplicado que faz sentido remover
- Regras de negócio mal posicionadas
- Responsabilidades confusas
No final, você terá um código mais organizado sem comprometer a estabilidade da aplicação.
Boas práticas para manter um projeto com Vertical Slice saudável
Adotar o Vertical Slice Pattern é um ótimo passo, mas manter o projeto organizado ao longo do tempo exige disciplina e algumas boas práticas simples.
Nomeie slices de forma clara
O nome da pasta deve deixar claro o que o sistema faz, não a tecnologia usada. Prefira nomes como:
create-userupdate-order-statusget-user-by-id
Evite nomes genéricos ou técnicos demais. Quanto mais próximo da linguagem do negócio, melhor.
Um slice, uma responsabilidade
Cada slice deve resolver um único problema. Se você sentir vontade de adicionar mais endpoints ou regras diferentes no mesmo slice, é um sinal de que ele está crescendo além do ideal.
Aceite duplicação consciente
Duplicar pequenas regras ou validações pode ser melhor do que criar dependências desnecessárias entre slices. O foco é independência e clareza, não reaproveitamento extremo.
Teste junto do slice
Sempre que possível, mantenha os testes próximos da funcionalidade que eles testam. Isso facilita manutenção e deixa claro o que está sendo validado.
Documente a intenção
Não é sobre documentar tudo, mas explicar por que aquele slice existe e qual problema ele resolve. Comentários simples já ajudam bastante quem chega depois.
Revise constantemente
Arquitetura não é algo fixo. Periodicamente, revise seus slices e veja se ainda fazem sentido. Ajustes pequenos evitam problemas grandes no futuro.
Conclusão
O Vertical Slice Pattern é uma abordagem moderna, prática e muito eficiente para organizar código, especialmente em projetos que crescem rápido e mudam com frequência. Ele muda o foco da arquitetura: em vez de pensar em camadas técnicas, você passa a pensar em funcionalidades reais do sistema.
Em frameworks como o NestJS, esse padrão se encaixa de forma natural e ajuda a criar aplicações mais fáceis de entender, manter e evoluir. Não é sobre seguir uma moda, mas sobre reduzir complexidade e melhorar a experiência de quem desenvolve.
Se você ainda não testou o Vertical Slice, experimente aplicá-lo em uma funcionalidade pequena. Os benefícios ficam claros rapidamente.
E agora quero saber de você:
Você já usa Vertical Slice nos seus projetos? Teve dificuldades ou benefícios claros? Deixa seu comentário aqui embaixo e vamos trocar ideia sobre arquitetura na prática.