Rafhael Marsigli Logo

Por que abandonei Form Requests e API Resources do Laravel e abracei Data + Value Objects

4 min de leitura
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_activestatus) 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.

Compartilhe com quem você gosta