Arquitectura Hexagonal en Laravel 12: Separando el Dominio del Framework sin Perder Productividad

22 May 2026 · 6 min · Arquitectura

Laravel es uno de los frameworks más productivos del ecosistema PHP. Su velocidad de desarrollo, ecosistema y simplicidad permiten construir aplicaciones completas en muy poco tiempo. Sin embargo, conforme un proyecto crece, el enfoque tradicional basado únicamente en MVC comienza a mostrar limitaciones importantes.

Controladores gigantes, lógica de negocio distribuida entre modelos y servicios, dependencia excesiva del framework y dificultad para testear correctamente son síntomas muy comunes en aplicaciones Laravel maduras.

Aquí es donde la arquitectura hexagonal comienza a tener sentido.

La arquitectura hexagonal no busca reemplazar Laravel. Busca evitar que el dominio de negocio dependa completamente del framework.

En este artículo explicaré cómo implementar arquitectura hexagonal real en Laravel 12 sin convertir el proyecto en una sobreingeniería innecesaria.

El Problema del MVC Tradicional en Laravel

Laravel promueve una estructura extremadamente cómoda:

  • Controllers

  • Models

  • Views

  • Services

El problema aparece cuando la aplicación empieza a crecer.

Muchos proyectos terminan así:

  • Controladores con cientos de líneas

  • Modelos Eloquent llenos de lógica de negocio

  • Servicios acoplados al framework

  • Dependencias imposibles de aislar

  • Testing lento y complejo

Laravel facilita mucho comenzar rápido, pero también facilita mezclar responsabilidades.

La productividad inicial muchas veces se convierte en deuda técnica silenciosa.

El verdadero problema no es usar Laravel. El problema es permitir que el framework se convierta en el centro absoluto de la arquitectura.

¿Qué Es Realmente la Arquitectura Hexagonal?

La arquitectura hexagonal, también conocida como Ports and Adapters, fue propuesta por Alistair Cockburn con una idea muy clara:

El dominio de negocio no debería depender de infraestructura externa.

Eso incluye:

  • Bases de datos

  • Frameworks

  • APIs

  • Colas

  • Sistemas de terceros

En lugar de que la lógica de negocio conozca Laravel, Laravel debería conocer la lógica de negocio.

Esto cambia completamente la dirección de las dependencias.

La Idea Central: Puertos y Adaptadores

La arquitectura hexagonal separa la aplicación en capas claramente definidas.

Dominio

Contiene las reglas reales del negocio.

  • Entidades

  • Value Objects

  • Contratos

  • Servicios de dominio

Esta capa no debería conocer Laravel.

Aplicación

Coordina casos de uso.

  • CreateUserUseCase

  • GenerateInvoiceUseCase

  • PublishArticleUseCase

Aquí vive la lógica operacional.

Infraestructura

Implementa detalles técnicos.

  • Eloquent

  • Redis

  • Queues

  • HTTP Clients

  • Storage

Esta capa depende del dominio, no al revés.

Cómo Organizar Carpetas en Laravel 12

Una de las decisiones más importantes es abandonar la organización puramente técnica.

En lugar de:

app/Models app/Services app/Http app/Repositories

Prefiero algo más orientado al dominio:

app/Core app/Core/User app/Core/User/Domain app/Core/User/Application app/Core/User/Infrastructure

Dentro:

app/Core/User/Domain/User.php app/Core/User/Domain/UserRepository.php app/Core/User/Application/CreateUserUseCase.php app/Core/User/Infrastructure/EloquentUserRepository.php

Esta estructura cambia completamente cómo evoluciona el proyecto.

Ahora el código está agrupado por contexto de negocio y no por tipo técnico.

Los Casos de Uso Son el Verdadero Centro

Uno de los mayores errores en Laravel es colocar lógica de negocio en controladores o modelos.

En arquitectura hexagonal, el verdadero corazón son los casos de uso.

Por ejemplo:

final class CreateUserUseCase { public function __construct( private UserRepository $users ) {}public function execute(CreateUserCommand $command): User { // lógica de negocio } }

El controlador únicamente coordina:

public function store(Request $request) { return $this->createUserUseCase->execute(...); }

Esto reduce enormemente el acoplamiento.

Eloquent Sigue Existiendo, Pero Aislado

Uno de los mayores malentendidos es pensar que arquitectura hexagonal significa dejar de usar Eloquent.

No realmente.

Eloquent sigue siendo extremadamente útil.

La diferencia es que deja de ser el núcleo del sistema.

Por ejemplo:

interface UserRepository { public function save(User $user): void; }

Implementación:

final class EloquentUserRepository implements UserRepository { public function save(User $user): void { UserModel::query()->create([...]); } }

Ahora el dominio conoce un contrato, no Eloquent.

Eso permite:

  • Cambiar infraestructura fácilmente

  • Mockear dependencias

  • Mejorar testing

  • Reducir acoplamiento

Testing Mucho Más Limpio

Uno de los mayores beneficios reales aparece en testing.

En MVC tradicional muchas pruebas requieren:

  • Base de datos

  • Framework bootstrapped

  • Eloquent

  • Factories

En arquitectura hexagonal, los casos de uso pueden probarse aislados.

public function test_user_can_be_created() { $repository = Mockery::mock(UserRepository::class);$useCase = new CreateUserUseCase($repository);$result = $useCase->execute(...);$this->assertTrue($result->isActive()); }

Esto genera pruebas:

  • Más rápidas

  • Más estables

  • Más enfocadas

Y sobre todo:

Permite validar reglas reales de negocio sin depender del framework.

Cuándo Vale la Pena Aplicarla

Aquí es donde debo ser muy honesto.

No todos los proyectos necesitan arquitectura hexagonal.

Aplicarla indiscriminadamente puede generar complejidad innecesaria.

Para un CRUD pequeño probablemente no vale la pena.

Pero comienza a ser extremadamente útil cuando existen:

  • Múltiples desarrolladores

  • Reglas de negocio complejas

  • Integraciones externas

  • Procesos críticos

  • Escalabilidad a largo plazo

  • Testing avanzado

Mi opinión personal es que muchos proyectos Laravel medianos y grandes deberían adoptar al menos una versión parcial de este enfoque.

No necesariamente arquitectura hexagonal pura.

Pero sí separación real entre dominio e infraestructura.

El Error de Sobrearquitectura

Uno de los peligros más grandes es intentar replicar Java Enterprise dentro de Laravel.

He visto proyectos con:

  • Interfaces innecesarias

  • Capas absurdas

  • Abstracciones vacías

  • Factories para todo

Eso destruye la productividad.

Laravel sigue siendo valioso precisamente por su velocidad.

La clave está en encontrar equilibrio.

La arquitectura debe reducir complejidad, no multiplicarla.

Mi recomendación es introducir arquitectura hexagonal únicamente en áreas críticas del negocio.

No es necesario transformar absolutamente todo.

Laravel 12 Facilita Mucho Este Enfoque

Laravel moderno ya ofrece herramientas muy compatibles con arquitectura limpia:

  • Container poderoso

  • Dependency Injection

  • Actions

  • Pipelines

  • Events

  • Queues

El framework no impide aplicar buena arquitectura.

De hecho, Laravel 12 facilita muchísimo construir aplicaciones desacopladas.

El problema normalmente no es técnico.

Es organizacional.

Muchos equipos nunca definen límites claros entre dominio e infraestructura.

Conclusión

Arquitectura hexagonal no es una moda arquitectónica.

Es una forma de proteger el dominio del negocio contra el paso del tiempo.

Laravel seguirá evolucionando.

Las librerías cambiarán.

Las bases de datos también.

Pero las reglas reales del negocio deberían permanecer estables.

Ese es el verdadero objetivo de separar el dominio del framework.

Mi experiencia personal es que muchos proyectos Laravel colapsan no por problemas de rendimiento, sino porque la lógica termina completamente mezclada con infraestructura.

Cuando eso ocurre, cualquier cambio se vuelve riesgoso.

La arquitectura hexagonal ayuda precisamente a evitar ese problema.

No porque sea perfecta.

Sino porque obliga a pensar en límites, responsabilidades y dependencias desde el inicio.

Y en aplicaciones grandes, eso marca una diferencia enorme.