Por que abandonei Form Requests e API Resources do Laravel e abracei Data + Value Objects
Spoiler: não foi porque o Laravel é ruim. Foi porque eu fiquei exigente.
Por muitos anos, eu fui 100% team Laravel nativo.
Usei Form Requests religiosamente para validação. Usei API Resources para transformar respostas. Defendi essas ferramentas em projetos, code reviews e discussões técnicas. E, sendo honesto, elas me serviram muito bem.
Mas conforme meus projetos foram crescendo — em complexidade, longevidade e responsabilidade — comecei a sentir que algo estava… fora do lugar.
Nada estava exatamente errado. Mas tudo estava espalhado demais.
Este post é sobre:
as dores reais que senti
o processo de questionar decisões antigas
por que migrei para Spatie Laravel Data + Value Objects
e as vantagens e desvantagens que aceitei conscientemente
Sem dogma. Sem hype. Só engenharia.
O incômodo começou pequeno (como sempre)
Tudo começou com aquela sensação clássica:
“Onde exatamente essa regra de negócio mora?”
Vamos a um exemplo real:
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'status' => $this->is_active ? 'active' : 'inactive',
];
}
}Controller no meio, models abaixo, services em algum lugar.
Funciona? Funciona - muito bem na verdade.
Mas perceba:
Validação está em um lugar
Transformação em outro
Tipagem… em lugar nenhum
Regra de conversão (
is_active→status) escondida no Resource
Nada disso quebra. Mas tudo isso fragmenta.
O problema não é o Laravel, é o acoplamento implícito
O que começou a me incomodar foi perceber que:
Form Requests validam, mas não representam dados
API Resources transformam, mas não garantem contrato
O formato real do dado só existe… na sua cabeça
E aí começam os sintomas:
Duplicação de regras
Testes mais verbosos do que deveriam
Frontend dependendo de “conhecimento tribal”
Refactors que dão medo
Foi aí que comecei a olhar com mais carinho para DTOs de verdade.
Não é sobre arrays com PHPDoc.
Mas sim sobre Objetos.
Entra em cena: Spatie Laravel Data
Quando comecei a usar Spatie Data, a diferença foi imediata.
use Spatie\LaravelData\Data;
class UserData extends Data
{
public function __construct(
public readonly string $name,
public readonly string $email,
public readonly bool $isActive,
) {}
}Agora:
O formato
A validação
O contrato
vivem juntos! Sem mágica.
Adeus API Resources (com carinho)
Aqui foi onde mais doeu emocionalmente 😅, API Resources são ótimos. Mas eles incentivam algo perigoso:
transformação tardia
Com Data Objects:
class UserData extends Data
{
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly string $email,
public readonly UserStatus $status,
) {}
}A transformação acontece antes.
O controller só orquestra:
return UserData::from($user);Sem lógica escondida.
Sem ifs mágicos no toArray().
Value Objects é o passo que completa o raciocínio
Foi impossível parar só no Data.
Se eu já estava tipando tudo… por que ainda usar string para coisas que não são strings? E se eu usar um Value Object para verificações importantes?
final class Email
{
public function __construct(public readonly string $value)
{
if (! filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
}
}Agora:
Um e-mail sempre é válido
Não existe estado inválido
A regra não se repete
Isso é libertador.
Mas qual foi o impacto real no dia a dia?
Depois da migração, percebi ganhos claros:
Vantagens
Contratos explícitos
Refactors muito mais seguros
Menos testes defensivos
Melhor integração com TypeScript
IDE trabalhando a meu favor
Desvantagens (sim, existem)
Mais classes
Curva de aprendizado para o time
Código inicial um pouco mais verboso
Menos "conveniência" imediata
Overengineer (muito, demais, ultra) para projetos pequenos
E eu estou 100% OK com isso.
Prefiro:
clareza agora do que dor depois
Não é sobre Spatie. É sobre maturidade
Este post não é um ataque ao Laravel.
É um reconhecimento de que:
Ferramentas nativas resolvem 80%
Projetos grandes vivem nos outros 20%
Spatie Data + Value Objects me deram algo que eu não tinha:
confiança estrutural
Hoje, quando eu refatoro, eu não torço para nada quebrar.
O compilador me avisa.
E isso, depois de anos apanhando de bugs silenciosos… não tem preço.
É uma obrigação?
Se você está confortável com Form Requests e API Resources, ótimo. Está tudo bem!
Mas se você começou a sentir aquele incômodo sutil… talvez seja hora de ouvir. Às vezes, mudar dói um pouco. Mas vale a pena.