<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: David_Creat</title>
    <description>The latest articles on Forem by David_Creat (@davidcreat).</description>
    <link>https://forem.com/davidcreat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2151927%2Fcf657e50-4752-48fc-b0b6-7db39a8fb59c.png</url>
      <title>Forem: David_Creat</title>
      <link>https://forem.com/davidcreat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/davidcreat"/>
    <language>en</language>
    <item>
      <title>Arquitectura Hexagonal con Spring Boot y Angular: lo que aprendí aplicándola en producción</title>
      <dc:creator>David_Creat</dc:creator>
      <pubDate>Mon, 20 Apr 2026 20:56:18 +0000</pubDate>
      <link>https://forem.com/davidcreat/arquitectura-hexagonal-con-spring-boot-y-angular-lo-que-aprendi-aplicandola-en-produccion-4hid</link>
      <guid>https://forem.com/davidcreat/arquitectura-hexagonal-con-spring-boot-y-angular-lo-que-aprendi-aplicandola-en-produccion-4hid</guid>
      <description>&lt;p&gt;La mayoría de los posts sobre arquitectura hexagonal hablan de mantenibilidad y testabilidad. Eso está bien, pero hay una dimensión que casi nadie menciona: &lt;strong&gt;la arquitectura hexagonal es, por diseño, una estrategia de reducción de superficie de ataque&lt;/strong&gt;. Cuando trabajé integrando pasarelas de pago en sistemas con lógica de negocio acoplada a la infraestructura, entendí que el problema no era solo de estructura de código, era de exposición de riesgo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbou7twlttjqefjv1of7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flbou7twlttjqefjv1of7.png" alt="Diagrama arquitectura hexagonal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El principio central: aislamiento como control de seguridad
&lt;/h2&gt;

&lt;p&gt;La arquitectura hexagonal establece que &lt;strong&gt;el dominio no depende de nada externo&lt;/strong&gt;. Desde una perspectiva de seguridad, esto es equivalente al principio de mínimo privilegio aplicado al código: cada capa solo conoce lo estrictamente necesario para cumplir su función.&lt;/p&gt;

&lt;p&gt;En un sistema acoplado, una vulnerabilidad en un adaptador HTTP puede propagarse directamente a la lógica de negocio porque no hay frontera clara. En hexagonal, el dominio está aislado detrás de interfaces (puertos), lo que significa que un adaptador comprometido tiene acceso limitado y controlado.&lt;/p&gt;

&lt;p&gt;Esto no es una metáfora, es &lt;em&gt;Defense in Depth&lt;/em&gt; aplicado a la arquitectura de software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo se ve esto en Spring Boot
&lt;/h2&gt;

&lt;p&gt;La estructura de paquetes no es solo organización, es un boundary de seguridad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/main/java/com/app/
├── domain/
│   ├── model/          # Entidades, value objects, reglas de negocio
│   └── port/           # Interfaces: lo único que el dominio expone
├── application/
│   └── usecase/        # Orquestación, validación de entrada, autorización
└── infrastructure/
    ├── persistence/    # Repositorios JPA (nunca acceden al dominio directamente)
    ├── rest/           # Controllers HTTP: primer punto de validación
    └── client/         # Clientes externos: terceros confinados aquí
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Los puertos como contratos de confianza cero&lt;/strong&gt;: Una interfaz bien definida en &lt;code&gt;domain/port&lt;/code&gt; actúa como un contrato de confianza cero. El dominio no necesita confiar en el adaptador concreto; confía en el contrato. Si el adaptador es reemplazado o comprometido, el dominio sigue operando con las mismas garantías.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// El dominio define el contrato, no la implementación&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Recibe un objeto de dominio puro, sin dependencias de infraestructura&lt;/span&gt;
    &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Payment&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Validación en los casos de uso, no en los adaptadores&lt;/strong&gt;: Un error común es delegar la validación al controller REST o al repositorio. Desde el punto de vista de seguridad, eso es confiar en que el adaptador sea honesto. La validación de invariantes de negocio debe vivir en &lt;code&gt;application/usecase&lt;/code&gt;, donde el código es independiente del vector de entrada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProcessPaymentUseCase&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt; &lt;span class="n"&gt;paymentGateway&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt; &lt;span class="n"&gt;paymentRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;PaymentResult&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProcessPaymentCommand&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Validación aquí, no en el controller.&lt;/span&gt;
        &lt;span class="c1"&gt;// Independiente de si la llamada viene de HTTP, una cola de mensajes o un test.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isNegativeOrZero&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvalidPaymentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"El monto debe ser positivo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;Payment&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Payment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;paymentGateway&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto es relevante en seguridad porque un atacante puede intentar alcanzar la lógica de negocio por múltiples vectores: HTTP, mensajes en cola (SQS/RabbitMQ), eventos de scheduler, etc. Si la validación está solo en el controller HTTP, los otros vectores quedan expuestos.&lt;/p&gt;

&lt;h2&gt;
  
  
  El riesgo real del código acoplado
&lt;/h2&gt;

&lt;p&gt;Cuando la infraestructura y el dominio están mezclados, el blast radius de una vulnerabilidad es máximo. Un ejemplo concreto: si un &lt;code&gt;@Repository&lt;/code&gt; JPA está inyectado directamente en un controller, y ese controller tiene una vulnerabilidad de inyección o de lógica de autorización, el atacante tiene acceso directo a la capa de datos sin pasar por ningún control de negocio.&lt;/p&gt;

&lt;p&gt;Con hexagonal, el camino forzado es:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request -&amp;gt; Controller (adapter) -&amp;gt; UseCase (application) -&amp;gt; Port (contract) -&amp;gt; Repository (adapter)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada flecha es un punto donde se puede aplicar un control de seguridad: autenticación, autorización, validación de entrada, rate limiting, auditoría. No es posible saltarse capas porque las dependencias simplemente no existen.&lt;/p&gt;

&lt;h2&gt;
  
  
  El complemento en Angular: no confiar en el frontend
&lt;/h2&gt;

&lt;p&gt;Desde el lado del cliente, la regla es la misma: el componente no debe acceder directamente a la API. Los servicios de Angular actúan como adaptadores que encapsulan la comunicación HTTP, pero también son el lugar correcto para centralizar el manejo de tokens, headers de seguridad y sanitización de respuestas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentApiService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;authService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt;  &lt;span class="c1"&gt;// El adaptador conoce el mecanismo de auth&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentRequest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// El componente nunca maneja tokens directamente&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/payments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpErrorResponse&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Manejo centralizado: no exponer stack traces al usuario&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;throwError&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La regla de oro desde seguridad: &lt;strong&gt;nunca confiar en validaciones del frontend&lt;/strong&gt;. Toda validación del cliente es UX, no seguridad. Los controles reales están en los casos de uso del backend.&lt;/p&gt;

&lt;p&gt;Cuando trabajo con &lt;strong&gt;Vite + React&lt;/strong&gt;, aplico la misma separación con custom hooks. El componente consume el hook, el hook es el único punto que conoce la API. Si hay que rotar credenciales, cambiar endpoints o agregar headers de seguridad, el cambio está en un solo lugar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auditoría y trazabilidad: el beneficio que nadie menciona
&lt;/h2&gt;

&lt;p&gt;Un sistema bien estructurado con hexagonal facilita enormemente la auditoría de seguridad. Porque todos los casos de uso son clases concretas con nombres explícitos, es trivial agregar logging de auditoría en un solo punto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Aspect&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuditAspect&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Around&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"execution(* com.app.application.usecase.*.*(..))"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;auditUseCase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ProceedingJoinPoint&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Cada operación de negocio queda registrada con usuario, timestamp y parámetros&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"USE_CASE_EXECUTED: {} by user: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSignature&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
            &lt;span class="nc"&gt;SecurityContextHolder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContext&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAuthentication&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;joinPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;proceed&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En un sistema acoplado, la lógica de negocio está dispersa y agregar auditoría implica tocar decenas de clases. En hexagonal, un aspecto sobre el paquete &lt;code&gt;usecase&lt;/code&gt; cubre todo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tres impactos concretos en seguridad
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reducción de superficie de ataque&lt;/strong&gt;: Los adaptadores de infraestructura solo exponen lo que el puerto define. No hay acceso directo entre capas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validación independiente del vector&lt;/strong&gt;: Las reglas de negocio se validan en los casos de uso, sin importar si la llamada viene de HTTP, una cola de mensajes o un job programado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blast radius controlado&lt;/strong&gt;: Si un adaptador es comprometido (por ejemplo, una librería de terceros con una CVE), el daño está contenido en esa capa. El dominio y los otros adaptadores no se ven afectados directamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cuándo NO aplicarla
&lt;/h2&gt;

&lt;p&gt;No es la arquitectura correcta para todo. Un CRUD de tres endpoints sin lógica de negocio no necesita este nivel de separación. El overhead de definir puertos e interfaces tiene costo real.&lt;/p&gt;

&lt;p&gt;Donde sí tiene sentido: sistemas que procesan pagos, datos personales o cualquier operación con implicaciones de compliance (PCI-DSS, SOC 2, ISO 27001). En esos contextos, la arquitectura hexagonal no es una preferencia de diseño, es casi un requerimiento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Alistair Cockburn - &lt;a href="https://alistair.cockburn.us/hexagonal-architecture/" rel="noopener noreferrer"&gt;Hexagonal Architecture (2005)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OWASP - &lt;a href="https://owasp.org/www-community/Security_by_Design_Principles" rel="noopener noreferrer"&gt;Defense in Depth&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tom Hombergs - &lt;a href="https://leanpub.com/get-your-hands-dirty-on-clean-architecture" rel="noopener noreferrer"&gt;Get Your Hands Dirty on Clean Architecture&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NIST - &lt;a href="https://csrc.nist.gov/glossary/term/least_privilege" rel="noopener noreferrer"&gt;Least Privilege Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Spring Docs - &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.structuring-your-code" rel="noopener noreferrer"&gt;Structuring Your Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>angular</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
