Pular para o conteúdo

Backend e API

Aplica-se quando a ADR entrega lógica de servidor. A stack está em Backend (stack); aqui estão os padrões de construção e a régua contra over-engineering.

Um endpoint pode ser um único arquivo: a Route Handler do Next.js valida com Zod, chama o Prisma e responde. Sem controller, sem service, sem repository. Não se cria camada por hábito — camada nova só entra quando paga o próprio custo (princípio 1, hipersimplicidade).

A régua para subir de camada é complexidade real, não estética. Se o arquivo continua legível e a lógica cabe na cabeça, ele fica como está.

Uma rota = um arquivo. Dentro dele, na ordem:

  1. Validação Zod da entrada — antes de qualquer processamento (princípio 7).
  2. Checagem de autenticação/autorização específica daquela rota — quem pode chamar isso, sobre quais recursos. O middleware genérico não decide isso por você.
  3. Lógica — Prisma direto na rota é aceitável quando a lógica é direta (CRUD, leitura simples, escrita simples com 1-2 regras).
  4. Resposta tipada conforme o schema Zod de saída.

Esse é o caminho padrão. A maioria dos endpoints fica assim e deve ficar assim.

Adicione a camada quando o sintoma aparecer, não antes:

  • Extrair um service — quando a mesma lógica de negócio é usada por mais de uma rota, ou quando a rota passa de ~50-80 linhas com regras de domínio que merecem teste unitário próprio.
  • Extrair um repository/dao — quando há consultas Prisma complexas, reaproveitadas, ou uma fronteira clara de persistência que o domínio quer ignorar. Para CRUD simples, não vale a pena.
  • Extrair um controller — raramente. Em Next.js a Route Handler já é o controller. Só faz sentido se houver orquestração não-trivial e reuso entre rotas.
  • Middleware — para concerns transversais (autenticação base, logging, rate-limit, CORS). Útil e recomendado, mas: o middleware autentica; quem autoriza a operação específica (esta conta pode editar este pedido?) é a rota. Misturar essas duas decisões no middleware é um anti-padrão — a regra fica longe do código que ela protege.

Quando o projeto cresce e várias rotas já justificaram quebras, esta organização funciona bem. Não é regra; é onde as coisas costumam parar quando precisam parar em algum lugar:

config/         ← configuração de banco, variáveis de ambiente, segurança
routes/         ← Route Handlers (o endpoint em si)
services/       ← lógica de negócio reusada por mais de uma rota
repositories/   ← (ou daos/) consultas Prisma complexas — só quando justificável
models/         ← (ou entities/) tipos e schemas Zod compartilhados
middlewares/    ← autenticação base, logging, rate-limit, CORS
workers/        ← consumidores de fila (ver stack de backend)

Estas valem mesmo no padrão mínimo de um arquivo:

  • Zod em toda entrada — sem exceção (princípio 7).
  • Autenticação antes de qualquer operação protegida — middleware base + checagem específica na rota.
  • Sem segredos no código; sem logar tokens, chaves de API ou payloads sensíveis.
  • Tipagem total ponta a ponta — any proibido (princípio 6).
  • Contrato OpenAPI sai do Zod — ver OpenAPI e Scalar.

Endpoints tipados, validados e autenticados. No menor número de arquivos possível para o que o domínio exige — nem menos (regras espalhadas), nem mais (camadas vazias).

Criado por Joseph Trupel