Ele começou com um .
Hoje tem 80 linhas.
Sabe como é: precisava barrar quem não tem assinatura ativa.
Um middleware, três linhas, resolvido.
Depois entrou o período de teste.
Depois o plano legado que tem regra diferente.
Depois "aproveita que já buscou a assinatura e desconta um crédito".
Depois o e-mail de aviso quando faltam 3 dias pro vencimento.
Hoje esse arquivo tem 80 linhas, faz quatro queries, altera dado no banco e dispara e-mail.
Ele não é mais um middleware. É um Service que mora na pasta errada e roda em todo request.
E o pior: essa regra não existe pro resto do seu sistema.
O middleware que virou gerente Funciona.
Passa nos testes de feature.
E tem quatro problemas escondidos que só aparecem meses depois.
Problema 1: middleware só existe no HTTP Esse é o grande.
Middleware é uma camada de request HTTP.
Ela não roda em outro lugar nenhum.
Então: O comando não desconta crédito.
O job na fila não desconta crédito.
Sua rota de API que você esqueceu de agrupar não desconta crédito.
O passa por cima de tudo.
Você não criou uma regra de negócio.
Criou uma regra da porta da frente.
Qualquer outra entrada no sistema ignora ela.
E, sério, isso não é hipótese: um dia alguém vai criar um endpoint novo, esquecer o middleware, e a assinatura vira um detalhe decorativo.
Problema 2: cobrou antes de saber se deu certo Repare na ordem: o acontece antes do .
O controller ainda vai rodar.
Pode estourar uma exceção, pode devolver erro de validação, o usuário pode ter mandado um PDF corrompido.
Não importa — o crédito já foi.
Cobrança é resultado da operação ter dado certo.
Não da requisição ter chegado.
Problema 3: ele decide como responder é ótimo pra quem está no navegador.
E é péssimo pra todo mundo mais.
Seu app mobile chama a API e recebe... um redirect com HTML de página de planos.
O front tenta dar e explode com um erro que não tem nada a ver com o problema real.
Problema 4: e-mail dentro do middleware Isso significa que todo request carrega a possibilidade de esperar um SMTP responder.
E se o servidor de e-mail estiver lento, seu app inteiro fica lento — inclusive pra quem não tem nada a ver com assinatura vencendo.
O que middleware faz bem Pensa nele como o porteiro do prédio.
Ele tem um trabalho só, e faz muito bem: decide quem passa e quem não passa — e ajusta detalhes na entrada e na saída.
Cabe no middleware: Autenticação e autorização de acesso (, , ) Rate limit () Definir idioma, timezone, tenant do request Mexer em request/response: limpar strings, adicionar header, forçar HTTPS Correlação e observabilidade: no contexto do log Não cabe: alterar dado de negócio, cobrar, enviar e-mail, disparar evento de domínio, decidir preço.
O porteiro confere se você mora no prédio.
Ele não reajusta seu condomínio.
O mesmo código, cada coisa no lugar O middleware volta a ser o que era: um porteiro.
Uma linha, uma decisão.
E deixa o Laravel resolver o formato da resposta: HTML pra navegador, JSON pra API.
Você não escolhe por ele.
O crédito vira responsabilidade de quem executa a ação: Agora a regra é do negócio, não do HTTP.
Rodou pelo painel, pela API, pelo comando agendado ou pela fila?
Mesma regra, mesma cobrança, mesma transação.
E o e-mail de "vence em 3 dias" nem devia estar no caminho de request nenhum: é um comando no scheduler rodando uma vez por dia.
A pegadinha: vindo Enquanto estamos aqui, a confusão mais comum de middleware: ordem.
Middleware global roda antes do .
Se você registrar algo global que usa , vai receber e um "call to a member function on null" que não faz sentido nenhum.
Se seu middleware depende de usuário logado, ele é de rota (ou de grupo), depois do .
Nunca global.
Bônus: e se for coisa pra depois da resposta?
Se a ideia era "registrar o acesso sem atrasar o usuário", existe o lugar certo: middleware terminable, com um método que roda depois da resposta ir pro navegador.
Mas se o dado importa de verdade, prefira um evento e um listener na fila.
Aí funciona igual em qualquer entrada do sistema — e é a mesma lógica de sempre: regra de negócio não deveria depender de como o request chegou.
Antes de você fechar a aba Teste rápido pro seu middleware: se essa mesma ação rodasse por um comando Artisan, a regra ainda precisaria valer?
Se sim, ela não é do middleware.
Ela é do domínio, e o middleware está só escondendo isso de você.
Porteiro barra ou libera.
Gerente decide o negócio.
Quando o porteiro começa a decidir o negócio, alguém entra pela garagem e ninguém percebe.
Me conta: qual o middleware mais gordo que você já viu?
Eu já achei um com 200 linhas que fazia login, criava tenant, populava dado inicial e mandava e-mail de boas-vindas — tudo em . 😬