4D
4DEVS
    Home
    Tools
GitHubTry Tools →
4D
4DEVS

Hub Tecnológico de referência. Ferramentas, artigos e recursos para engenheiros de software.

Newsletter

Artigos exclusivos, tips de performance e releases de ferramentas. Sem spam.

Você receberá um email de confirmação. Sem spam — pode cancelar a qualquer momento.

Plataforma
  • Blog
  • Ferramentas
  • Parceiros
Ferramentas
  • HASH Generator
  • UTM Generator
  • JSON Formatter
  • Base64 Codec
  • Color Converter
Recursos
  • Laravel
  • Next.js
  • Architecture
  • Security
  • DevOps

© 2026 4DEVS. Todos os direitos reservados.

Tech Partner:TRUST DEV
Voltar ao Blog
Laravel

Arquitetura Hexagonal em Laravel: Além do MVC

Como estruturar projetos Laravel grandes usando princípios de Clean Architecture sem perder a pragmaticidade do framework.

1 de março de 20263 min de leitura
ArchitectureClean CodeDesign Patterns

O padrão MVC (Model-View-Controller) é a porta de entrada para 99% dos desenvolvedores Laravel. Ele é fantástico para produtividade e entrega rápida (Time-to-Market). No entanto, à medida que a regra de negócios cresce e o domínio se torna complexo, os Controllers ficam inflados (Fat Controllers) e os Models assumem responsabilidades que vão muito além da persistência de dados.

É aqui que a Arquitetura Hexagonal (Ports and Adapters) entra em cena. O objetivo não é lutar contra o Laravel, mas sim isolar o núcleo da sua aplicação (Domínio) das tecnologias externas (Framework, Banco de Dados, APIs de terceiros).

O Problema do Acoplamento no Eloquent

O Active Record do Eloquent é poderoso, mas ele acopla intimamente a sua regra de negócio à infraestrutura de banco de dados. Veja este exemplo comum:

public function processPayment(Request $request, Order $order)
{
    if ($order->status !== 'pending') {
        throw new Exception('Order already processed');
    }

    $payment = Stripe::charge($request->stripe_token, $order->total);
    
    $order->update(['status' => 'paid', 'transaction_id' => $payment->id]);
    
    return response()->json(['success' => true]);
}

Problemas com o código acima:

  1. O Controller sabe sobre HTTP (Request), Banco de Dados ($order->update) e APIs externas (Stripe).
  2. É impossível testar a regra de negócio sem fazer um mock de chamadas HTTP reais e tocar no banco de dados.

Implementando Portas e Adaptadores

Na Arquitetura Hexagonal, o fluxo de dependência aponta sempre para o centro (Domínio).

1. O Caso de Uso (Application Layer)

Vamos extrair a lógica para um Use Case (ou Action, na terminologia comum do Laravel).

namespace App\Domain\Order\UseCases;

use App\Domain\Order\Ports\PaymentGatewayInterface;
use App\Domain\Order\Ports\OrderRepositoryInterface;

class ProcessOrderPayment
{
    public function __construct(
        private OrderRepositoryInterface $orderRepository,
        private PaymentGatewayInterface $paymentGateway
    ) {}

    public function execute(string $orderId, string $paymentToken): void
    {
        $order = $this->orderRepository->findById($orderId);

        if (!$order->isPending()) {
            throw new DomainException('Order cannot be processed.');
        }

        $transactionId = $this->paymentGateway->charge($paymentToken, $order->getTotal());

        $order->markAsPaid($transactionId);
        $this->orderRepository->save($order);
    }
}
💡

Note que o Use Case não sabe se estamos usando Stripe, PayPal ou Eloquent. Ele depende apenas de abstrações (Interfaces), que são as nossas Portas.

2. Os Adaptadores (Infrastructure Layer)

Agora, implementamos as interfaces usando as ferramentas do Laravel.

namespace App\Infrastructure\Adapters;

use App\Domain\Order\Ports\PaymentGatewayInterface;
use Stripe\StripeClient;

class StripePaymentAdapter implements PaymentGatewayInterface
{
    public function charge(string $token, float $amount): string
    {
        // Implementação real da SDK do Stripe
        return 'txn_12345';
    }
}

E no AppServiceProvider, fazemos o bind da Porta para o Adaptador:

$this->app->bind(PaymentGatewayInterface::class, StripePaymentAdapter::class);

Conclusão

Não aplique Arquitetura Hexagonal em CRUDs simples. O custo da abstração não compensa. No entanto, para Core Domains (o coração do seu negócio), o isolamento garante que o seu software sobreviva às mudanças de versão do framework, substituições de gateways de pagamento e, acima de tudo, permite testes unitários que rodam em milissegundos.