El problema que todos reconocemos
Todo equipo que lleva unos años manteniendo software ha vivido la misma historia: el proyecto empieza limpio, pero con el tiempo la lógica de negocio se va enredando con el framework, la base de datos, los controladores, las colas y las integraciones externas. Llega un día en que cambiar cualquier pieza —migrar la base de datos, cambiar el proveedor de email, actualizar el framework— implica tocar medio proyecto, y el miedo a romper algo paraliza las decisiones técnicas.
La arquitectura hexagonal existe precisamente para evitar ese final. No es una moda ni un ritual académico: es una forma concreta de organizar el código para que lo importante (tu negocio) no dependa de lo accesorio (la tecnología).
Qué es la arquitectura hexagonal
La arquitectura hexagonal —también llamada Ports & Adapters— fue descrita por Alistair Cockburn en 2005. Su idea central es sencilla: colocar el dominio (las reglas de negocio, lo que hace única a tu aplicación) en el centro del sistema, completamente aislado del exterior, y conectarlo con el mundo real a través de dos tipos de piezas:
- Puertos (ports): interfaces que define el propio dominio. Declaran qué necesita el negocio («guardar una factura», «enviar una notificación») sin decir cómo se hace.
- Adaptadores (adapters): implementaciones concretas de esos puertos. Un adaptador sabe hablar con MySQL, con Redis, con la API de un tercero o con la consola. El dominio no sabe —ni le importa— cuál está enchufado.
El hexágono es solo una metáfora visual: cada «lado» representa un punto de conexión con el exterior. Lo importante no es la forma, sino la regla de dependencia: las dependencias siempre apuntan hacia dentro. La infraestructura depende del dominio, nunca al revés.
Las tres capas, en la práctica
- Dominio: entidades, value objects y reglas de negocio puras. Cero imports de framework, cero SQL, cero HTTP. Es código que podrías ejecutar dentro de veinte años con otra tecnología.
- Aplicación: los casos de uso del sistema (crear un presupuesto, publicar un artículo). Orquesta el dominio y define los puertos que necesita. Aquí encajan patrones como command handlers y CQRS.
- Infraestructura: todo lo técnico —controladores HTTP, repositorios Doctrine, clientes de APIs, workers de cola— implementando los puertos que el dominio y la aplicación han definido.
Un ejemplo mínimo
Imagina un caso de uso «publicar un artículo». El puerto lo define la aplicación:
interface ArticleRepositoryInterface
{
public function save(Article $article): void;
}
El handler solo conoce esa interfaz:
final readonly class PublishArticleHandler
{
public function __construct(
private ArticleRepositoryInterface $repository
) {}
public function __invoke(PublishArticleCommand $command): void
{
$article = $this->repository->findById($command->id);
$article->publish(); // la regla de negocio vive en el dominio
$this->repository->save($article);
}
}
Y en infraestructura vive el adaptador que habla con MySQL vía Doctrine. ¿Mañana queremos cambiar a otra base de datos o añadir una caché? Se escribe un adaptador nuevo y se enchufa. El dominio y el caso de uso no se enteran.
Qué beneficios reales aporta
Después de años aplicándola en proyectos de todo tipo, estos son los beneficios que de verdad notan nuestros clientes:
- Testabilidad radical: el dominio se testea sin levantar framework, base de datos ni contenedores. Los tests de negocio son rápidos y estables, lo que se traduce en menos regresiones y entregas más seguras.
- Tecnología reemplazable: cambiar de base de datos, de proveedor cloud o de framework deja de ser un proyecto en sí mismo. Se reescribe un adaptador, no la aplicación.
- Deuda técnica bajo control: la estructura obliga a que las reglas de negocio tengan un lugar único y explícito. El código nuevo no «se esconde» en controladores.
- Equipos que escalan: con límites claros entre capas, varias personas pueden trabajar en paralelo sin pisarse, y los perfiles nuevos entienden la estructura en días, no en meses.
- Decisiones posponibles: puedes empezar con lo simple (un adaptador local) y cambiar a lo serio (S3, una cola, un proveedor externo) cuando el negocio lo pida, sin reescribir nada.
Cuándo NO la recomendamos
La honestidad también es parte de la experiencia. La arquitectura hexagonal añade estructura, y la estructura cuesta: más interfaces, más clases, más disciplina. Hay casos donde no compensa:
- Prototipos y MVPs descartables: si el objetivo es validar una idea en dos semanas, montar capas es frenar. Eso sí: si el prototipo cuaja, conviene refactorizar pronto, porque ese código «temporal» siempre acaba siendo producción.
- CRUDs triviales sin reglas de negocio: un micro backoffice de mantenimiento con cuatro formularios no necesita puertos ni adaptadores.
- Scripts y herramientas de un solo uso.
Para todo lo demás —productos que van a vivir años, sistemas que integran terceros, plataformas con varios equipos— la inversión se devuelve con creces a partir del primer cambio grande.
Cómo la aplicamos nosotros
No es teoría: es nuestra forma estándar de trabajar. Toda nuestra plataforma está construida con arquitectura hexagonal, domain-driven design y bounded contexts desplegados como microservicios independientes. Combinada con CQRS y eventos de dominio, nos permite cosas que con una arquitectura tradicional serían impensables: sustituir el almacenamiento de ficheros de un servicio por object storage sin tocar una línea de negocio, o poner en producción un contexto nuevo sin redeployar los demás.
De hecho, este blog que estás leyendo se sirve desde uno de esos microservicios, construido exactamente con los principios que acabamos de describir.
¿Tiene sentido para tu proyecto?
Si tu aplicación acumula años de desarrollo, cada cambio cuesta más que el anterior y el equipo ha dejado de proponer mejoras «porque es muy arriesgado», el problema casi nunca es el equipo: es la arquitectura. La buena noticia es que no hace falta reescribir desde cero —se puede migrar de forma gradual, empezando por los módulos que más duelen.
Si quieres una valoración honesta de tu caso, habla con nuestro equipo: revisamos el estado de tu arquitectura, te decimos qué mejoraría con una migración y —igual de importante— qué no hace falta tocar.